nativephp/mobile-ui
Native UI components for NativePHP mobile apps. nativephp/mobile-ui provides ready-made elements that render as native screens, helping you build consistent mobile interfaces quickly without writing Swift or Kotlin.
nativephp/mobile-ui is the native chrome layer for a NativePHP Mobile app: it gives you real iOS/Android UI elements (top bars, bottom tabs, side navigation, and a small set of native primitives) that render outside the WebView, on top of your normal Laravel/Livewire screens. If you have ever shipped a NativePHP app that looked like a website in a shell, this is the package that fixes the frame.
Minimum path to a first win:
nativephp/mobile app (an android/ and/or ios/ folder, a successful php artisan native:run). This package does nothing in a browser.composer require nativephp/mobile-ui, then re-install the native dependencies (php artisan native:install or the package's install command) so the Swift/Kotlin side gets the component code.php artisan vendor:publish --tag=nativephp-ui) and skim it before writing markup — colours, default bar behaviour, and safe-area handling usually live there.resources/views/components) and src/ — the component names are the whole API, and the README tends to lag behind the code in small packages like this.Budget half a day for step 5. Everything after that is repetition.
Native chrome in the layout, content in the view. The productive mental model is: your Blade layout owns the native bars, your Livewire components own the body. Put the top bar and bottom nav in layouts/app.blade.php so every screen inherits them, and let individual views override slots (title, trailing actions) via section-style props rather than duplicating bar markup per page.
Tabs as routes, not as client state. The cleanest bottom-nav setup maps each tab to a route (and therefore a Livewire page), with the native component carrying the active-tab indicator. Avoid driving tab content by toggling @if blocks in one giant view — you lose deep-linking, back-button behaviour, and Livewire's per-page lifecycle.
Treat the native layer as an event bus, not a DOM. Anything the native bar knows (button tapped, tab switched, search submitted) arrives as an event into your Livewire component; anything your component knows must be pushed back out. Write a tiny NativeUi service or trait that wraps dispatch/listen calls so you're not scattering raw event strings across ten components. This wrapper is the single most valuable thing you'll write in the first week.
Platform branching is normal, not a smell. iOS and Android disagree about bar height, back affordance, and tab labels. Use the platform directives or a config-driven variant so you can adjust one without breaking the other, and test both. A layout that looks correct on iOS is routinely clipped on Android.
Compose with existing Blade, don't rewrite it. Use native UI for frame-level elements (bars, tabs, modals, action sheets) and keep forms, lists, and rich content in the WebView. The seam between native and web is where bugs live — fewer seams is better.
Icons and assets typically need to be registered or bundled with the native build rather than referenced by URL. Keep a single icon map in config so adding a tab doesn't mean touching three files.
style attribute, no Tailwind class, no dark-mode media query will affect a native bar. Everything is config or props. If a colour won't change, you're editing the wrong layer.php artisan serve, CI) can produce errors or invisible output. Wrap usage behind a runtime check, or provide a Blade fallback, so your test suite and local web preview keep working.updated/mounted rather than setting titles declaratively and hoping.composer.json, read the changelog before upgrading, and avoid building abstractions directly on top of component names you don't control; your wrapper layer is the buffer.native:log or the platform tooling) and storage/logs/laravel.log — the cause is frequently on the side you didn't look at first.How can I help you explore Laravel packages today?