Tilly The Coder
Tilly The Coder
NativePHP for Mobile v2: real native components
Tilly The Coder

NativePHP for Mobile v2: real native components

Tilly The Coder
6 mins
This is the estimated time it takes to read the article.

NativePHP for Mobile v2 is a big step forward for “Laravel on mobile”, not because it changed what you can build, but because it changed how native it can feel while still letting you write Blade, Laravel routes, and the same UI stack you already like.

The standout feature is the new native component system (EDGE), but v2 also ships with a better frontend/dev workflow (proper Vite HMR), a typed JavaScript bridge, and cleaner async APIs.

In this guide

  • EDGE: native UI components defined in Blade

  • What components you can use today (Top Bar, Bottom Nav, Side Nav, FAB)

  • Required-props validation + icons

  • Typed JavaScript bridge (#nativephp)

  • Vite + HMR workflow for fast iteration

  • The painless v1 → v2 upgrade path

What’s new in v2 (the headline list)

NativePHP’s own v2.0.0 changelog calls out these pillars:

  • A new JavaScript/TypeScript bridge (fully typed)

  • EDGE (Element Definition and Generation Engine): render navigation UI as true native components from Blade

  • Laravel Boost support

  • HMR overhauled (full Vite HMR, plus platform-friendly setup)

  • A fluent “Pending API” for async methods (better DX + IDE help)

EDGE: native components, defined in Blade

EDGE (Element Definition and Generation Engine) is NativePHP Mobile’s component system that turns Blade component syntax into platform-native UI elements that live outside the web view lifecycle. In practice, that means your navigation chrome can be genuinely native and persistent, even if your main content still lives in a web view.

How it works (conceptually)

  • You define EDGE components in Blade (often in your main layout).

  • When Laravel renders the page, those Blade components compile down into a simple JSON configuration.

  • That configuration is passed to the native app, which renders the built-in native UI elements.

The core EDGE navigation components (today)
NativePHP’s EDGE docs currently focus on three main navigation components:

  • Top Bar (title bar with action buttons)

  • Bottom Navigation (always-accessible bottom bar)

  • Side Navigation (slide-out drawer)

Here’s a minimal Bottom Nav example:

<native:bottom-nav>
    <native:bottom-nav-item id="home" icon="home" label="Home" url="/home" />
</native:bottom-nav>

Where to define these
You can define them anywhere, but they only get processed when the Blade file is rendered. The docs recommend putting them in something that renders on every request (like layouts/app.blade.php).

Also in v2: a Floating Action Button component

NativePHP’s v2 components work is bigger than just navigation: the team has also shown a <native:fab> component (floating action button) as part of the early “real native components powered by Blade” set.

(If you’re writing an “app shell” layout, the FAB is the kind of component that instantly makes the app feel like a real mobile UI instead of “a web page in a wrapper”.)

Props validation: the “why isn’t this showing?” problem gets solved

EDGE components enforce required props validation with clear runtime errors. For example, if you forget label on a bottom-nav item, you’ll get a direct message telling you what’s missing.

This is one of those boring features that saves hours in real projects.

Icons got leaner (and more platform-native)

Recent v2 updates improved icon rendering by switching from a heavy icon library to a much smaller font-based approach, and on iOS supporting direct SF Symbol paths (while keeping cross-platform aliases).

Translation: smaller app footprint + easier “make it feel iOS-ish / Android-ish” polish.

Using Inertia? Make EDGE links behave like Inertia navigation

By default, links in EDGE components do a full post-back. If you’re using Inertia and want link taps to behave like <Link>, the docs suggest attaching the Inertia router to window.router:

import { router } from '@inertiajs/vue3';

window.router = router;

That way, EDGE links can route through Inertia instead of doing a full navigation cycle.

Typed JavaScript bridge: call native APIs from Vue/React like you mean it

v2 ships a brand-new JS bridge library with TypeScript declarations, designed for Vue/React/Inertia (and vanilla JS).

Set up an import alias in package.json:

{
  "imports": {
    "#nativephp": "./vendor/nativephp/mobile/resources/dist/native.js"
  }
}

Then import what you need:

import { on, off, Microphone, Events } from '#nativephp';

Microphone.record();

on(Events.Microphone.MicrophoneRecorded, () => {
  // update UI
});

This is a huge DX win for SPA-style mobile builds: native calls feel like normal frontend code, and your IDE can autocomplete everything.

HMR + Vite workflow: faster feedback loops

v2 overhauls Hot Module Replacement and provides a NativePHP Vite plugin.

In vite.config.js, you’ll typically add:

import { nativephpMobile, nativephpHotFile } from './vendor/nativephp/mobile/resources/js/vite-plugin.js';

export default defineConfig({
  plugins: [
    laravel({
      input: ['resources/css/app.css', 'resources/js/app.js'],
      refresh: true,
      hotFile: nativephpHotFile(),
    }),
    nativephpMobile(),
  ],
});

And when building platform bundles:

npm run build -- --mode=ios
npm run build -- --mode=android

To compile and run the app:

php artisan native:run

All straight from the docs — no “learn Xcode/Gradle just to refresh the screen” energy unless you want it.

Fluent Pending API: async native calls read better

In v2, async methods now implement a fluent API pattern (better IDE support + readability). One example in the changelog is Dialog::alert(...):

Dialog::alert('Confirm', 'Delete this?', ['Cancel', 'Delete'])
    ->remember()
    ->show();

And the JS side follows a similar “builder-like” style.

Other v2 improvements you’ll actually notice

A few practical updates called out in the v2 changelog:

  • Automatically handle common URL schemes like tel:, mailto:, sms:, geo:, facetime:

  • Android deep links / app links support

  • System::appSettings() to open OS settings for your app

  • Edge::clear() to remove EDGE components

  • native:install gets --fresh / -F aliases (and improved behavior on slow networks)

Upgrading from v1 to v2 (the “painless” path)

NativePHP’s own “Mobile v2 is here” post describes the upgrade as: update your composer requirement to ~2.0.0, then run:

composer update
php artisan native:install --force

…and you’re done.

Wrap-up

NativePHP for Mobile v2 is where the platform stops feeling like “Laravel in a mobile web view” and starts feeling like a genuine mobile app stack; because the UI framing (navigation, bars, actions) can now be truly native, defined using Blade.

If you’re building a mobile app where first impressions matter, start with EDGE: drop a Top Bar, wire up a Bottom Nav, add a Side Nav, and you’ll immediately feel the difference.