Originally published on php-apps.learnio.dev — part of the Using Native PHP course. View this lesson on the original site.

From browser to phone: the NativePHP dev loop

In the last lesson you scaffolded a Laravel app and confirmed it runs in the browser — Herd, Sail, or php artisan serve. That is the right first step. Laravel logic is easiest to build and debug when you can refresh a tab and see the result immediately.

Mobile development adds a second surface: your phone or a simulator. The same Laravel codebase runs there, but getting code from your machine onto the device needs its own workflow. NativePHP gives you three Artisan commands for that — plus a companion app called Jump.

If you already scaffolded a generic Laravel app in the last lesson, the section below walks you through turning it into a NativePHP project and running Jump. Chapter 2 goes deeper on environment constraints, Xcode, and troubleshooting — but you do not need to wait if your machine is ready now.

Set up a generic Laravel app for NativePHP

Start in the Laravel project you created in lesson 1.8 — the one that already loads the welcome page in your browser. NativePHP installs on top of that project; you do not need a separate mobile codebase.

Step 1: Add the NativePHP package

From your project root:

cd my-app
composer require nativephp/mobile

This adds the mobile package and registers the Artisan commands (native:jump, native:run, native:watch, and others).

Step 2: Set your app ID and run the installer

Before running the installer, add a unique app identifier to .env. Use reverse-DNS format — your domain or company name, plus the app name:

NATIVEPHP_APP_ID=com.yourcompany.myapp

If you plan to run on a real iOS device later, you can also set your Apple Developer team ID now (optional for Jump):

NATIVEPHP_DEVELOPMENT_TEAM=XXXXXXXXXX

Run the installer:

php artisan native:install

The installer creates config/nativephp.php and a nativephp/ directory with the iOS and Android shell projects. Treat nativephp/ as generated output — add it to .gitignore and do not edit those files by hand under normal circumstances.

If the installer asks about ICU-enabled PHP binaries, choose ICU if you plan to use Filament or anything that needs the intl extension. Otherwise the default build is fine.

Docs: nativephp.com/docs/mobile/3/getting-started/installation

Step 3: Install Jump on your phone

Jump is a companion app — not something you install via npm or Composer.

  1. Download Jump on your phone from bifrost.nativephp.com/jump (App Store or Google Play).
  2. Put your phone and laptop on the same Wi-Fi network. Guest networks that isolate devices from each other will not work.

Step 4: Start Jump from your Laravel project

Open a terminal in your project and run:

php artisan native:jump

A QR code appears in the terminal. Open Jump on your phone, scan it, and your Laravel app loads on device.

If you are already serving Laravel another way — Herd, Sail, or php artisan serve in another tab — tell Jump not to start its own server:

php artisan native:jump --no-serve --laravel-port=8000

For Herd, use the port Herd assigns (often 80 on a .test domain — check your setup). The --laravel-port flag must match wherever Laravel is actually listening.

For hot reload on Blade, CSS, and JS changes, run Vite in a second terminal while Jump is active:

npm run dev

Jump proxies Vite's HMR to your phone automatically — no extra Vite config required.

flowchart TD
    A[Generic Laravel app\nfrom lesson 1.8] --> B[composer require nativephp/mobile]
    B --> C[Set NATIVEPHP_APP_ID in .env]
    C --> D[php artisan native:install]
    D --> E[Install Jump app on phone]
    E --> F[Same Wi-Fi network]
    F --> G[php artisan native:jump]
    G --> H[Scan QR code]
    H --> I[App on device]
    I --> J{Need full build?}
    J -->|No — keep developing| I
    J -->|Yes — simulator / release| K[php artisan native:run]

Step 5: When you need a full native build

Jump is enough for most day-to-day work. When you need a simulator, a packaged build, or to test plugin native code:

php artisan native:run

Follow the prompts to pick iOS or Android and a target device. Add --watch to hot-reload during that build:

php artisan native:run --watch

Or run the watcher separately:

php artisan native:watch ios

Verify the app still works in the browser before your first native run — Laravel exceptions are easier to read in a tab than on a phone screen.

Two ways to develop on device

Think of mobile development in NativePHP as two modes:

Mode Command Best for
Fast preview on a real phone php artisan native:jump Day-to-day coding, hot reload, no Xcode/Android Studio required
Full native build php artisan native:run Simulators, packaged builds, testing plugins and release behaviour

Most of your time in this course will be in Jump mode until you are preparing store-ready builds.

flowchart LR
    A[Laravel app\nrunning locally] --> B{Ready to test\non device?}
    B -->|Fast iteration| C[native:jump\n+ Jump app on phone]
    B -->|Full build| D[native:run\nsimulator or device]
    C --> E[Edit PHP / Blade\nsee changes on phone]
    D --> F[native:watch\noptional hot reload]
    E --> A
    F --> D

Jump: preview on your phone without a build

Jump is a free companion app you install on your iPhone or Android device. It connects to your development machine over the same Wi-Fi network and renders your Laravel app inside a native shell — without compiling an Xcode or Android Studio project each time you change a line of code.

When you run:

php artisan native:jump

NativePHP starts a local dev server, prints a QR code in your terminal, and opens a WebSocket bridge between your machine and the Jump app. Scan the QR code with Jump on your phone and your Laravel app appears on device.

Under the hood, three things happen at once:

  1. Your Laravel app is served locally (via artisan serve, unless you already have Herd or Sail running and pass --no-serve).
  2. A bridge handles native API calls — camera, storage, biometrics — between PHP on your machine and the Jump shell on your phone.
  3. If you also run npm run dev, Vite hot module replacement is proxied through the bridge so Blade and front-end changes reload on the phone without a manual refresh.

Jump is the fastest way to see your work on a real device. You do not need Xcode installed to test on iOS. You do not need a USB cable. Phone and laptop just need to be on the same network.

Install Jump from bifrost.nativephp.com/jump — see the setup steps above if you have not done this yet.

Docs: nativephp.com/docs/mobile/3/the-basics/jump

native:run: compile and launch on a simulator or device

When you need a real native build — testing a simulator, verifying bundled assets, or checking behaviour that only appears in a packaged app — use:

php artisan native:run

This command compiles your Laravel project into the iOS or Android shell and launches it on a connected device or simulator. It is slower than Jump because it goes through the full build pipeline, but it is what you use when Jump's preview mode is not enough.

Common options:

# Target a platform directly
php artisan native:run ios
php artisan native:run android

# Build and watch in one step
php artisan native:run --watch

native:run also checks for unregistered plugins before building and warns you if any are missing — catching configuration mistakes before a long compile.

Use native:run when you are testing release builds, plugin native code, or simulator-specific behaviour. Use Jump for everything else during feature development.

native:watch: hot reload during a native build

If you are already running an app via native:run and want file changes pushed to the device automatically:

php artisan native:watch

Or combine build and watch in one command:

php artisan native:run --watch

native:watch is a long-lived process. It monitors your source files and syncs changes to the running app on the simulator or device. For this to work with Vite assets, your dev machine and test device must be on the same Wi-Fi network, and npm run dev should be running alongside the watcher.

On macOS you can watch iOS and Android simultaneously in separate terminals:

# Terminal 1
php artisan native:watch ios

# Terminal 2
php artisan native:watch android

How this fits your daily workflow

A typical session in this course looks like this:

  1. Build or change a feature in Laravel — prove it in the browser first (lesson 1.8).
  2. Start Jump for quick on-device feedback: php artisan native:jump, scan the QR code, keep coding.
  3. When you need a full build — before a chapter checkpoint or store prep — switch to php artisan native:run.

The browser remains your fallback. If something looks wrong on the phone, reproduce it at http://my-app.test or http://127.0.0.1:8000 first. That tells you whether the bug is Laravel logic or the native layer.

What to do now

If you have a generic Laravel app from lesson 1.8, work through the setup steps above in order: composer require, set NATIVEPHP_APP_ID, native:install, install Jump on your phone, then native:jump. Chapter 2 covers platform-specific tooling (Xcode, Android Studio, network troubleshooting) if anything blocks you.

Keep proving features in the browser first. Jump and native:run both use the same Laravel codebase — the browser is still your fastest debugger when something looks wrong.

If it goes wrong

  • composer require fails: confirm PHP 8.3+ and run composer update after checking version constraints in the NativePHP docs.
  • native:install errors on app ID: ensure NATIVEPHP_APP_ID is set in .env before running the installer.
  • Jump cannot connect: phone and laptop on the same Wi-Fi; disable VPN; try php artisan native:jump --ip=YOUR_LAN_IP.
  • QR code scans but the app is blank: confirm php artisan key:generate ran and check storage/logs/laravel.log.
  • Already using Herd or Sail: pass --no-serve and point --laravel-port at your running server.
  • native:run fails immediately: run php artisan native:plugin:register if unregistered plugins are reported.
  • Hot reload not working: run npm run dev in a second terminal while Jump or native:watch is active.

Remember

Browser first, phone second. Jump for speed, native:run for real builds, native:watch when you are iterating inside a native build. You will use all three before this course is done.

From Using Native PHP — Introduction and first screen on mobile