5 min read

NativePHP Mobile v3: The Persistent PHP Runtime Changes Everything

NativePHP Mobile v3 boots Laravel once and reuses the kernel, cutting response times from ~200-300ms to ~5-30ms, plus a real background queue worker.

Featured image for "NativePHP Mobile v3: The Persistent PHP Runtime Changes Everything"

When NativePHP Mobile shipped its v1 launch earlier this year, the reaction from Laravel developers was somewhere between disbelief and delight. You could build a real iOS and Android app with the same Blade, Livewire, and Eloquent you already knew. The catch, and there is always a catch, was performance. Every request inside the WebView triggered a fresh PHP process: boot the framework, register service providers, resolve the container, handle the request, tear it all down. That cold boot cost roughly 200 to 300 milliseconds per interaction, and on a phone that lag is felt.

NativePHP Mobile v3 fixes that at the foundation. The headline feature of the v3.1 line is a persistent PHP runtime: Laravel boots once when your app launches, and the same kernel is reused across every subsequent request. Response times drop to somewhere in the 5 to 30 millisecond range. That is not a marginal tuning win, it is the difference between an app that feels like a website in a wrapper and one that feels native.

What actually changed under the hood

In the old model, the mobile shell treated each navigation or bridge call like a short-lived CLI invocation. PHP started, Laravel bootstrapped, the response came back, and the process exited. That request-per-process design is simple and safe, because nothing leaks between requests, but bootstrapping a modern Laravel app is not free. Service providers, config caching, route registration, and container bindings all add up.

The persistent runtime flips the model. The PHP interpreter stays resident, Laravel’s kernel is booted a single time, and each incoming request is dispatched against the already-warm application. If you have ever run Laravel Octane, FrankenPHP worker mode, or RoadRunner on the server side, the mental model is identical: pay the bootstrap cost once, amortize it across thousands of requests. NativePHP has essentially brought worker-mode thinking to a phone.

That shift is why the numbers move so dramatically. You are no longer paying for bootstrap/app.php on every tap. The tradeoff is the same one worker mode always carries: because the application stays alive between requests, you have to be a little more disciplined about static state and long-lived singletons. The good news is that if your code already behaves well under Octane, it will behave well here.

The background queue worker is the sleeper feature

Persistent runtime gets the headlines, but the feature I think most apps will lean on is the background queue worker, also introduced in the v3.1 line and built on thread-safe (ZTS) PHP.

Historically, doing real background work in a mobile PHP app was awkward. Anything heavy on the main thread froze the UI. NativePHP now runs a dedicated PHP runtime on a separate thread that polls Laravel’s queue and executes jobs off the main thread. On both iOS and Android. Setup is almost insultingly simple:

# .env
QUEUE_CONNECTION=database

That is the entire configuration. The worker starts automatically when your app boots. There is no supervisor to configure, no artisan command to babysit, no daemon to register with the OS. You dispatch jobs exactly the way you always have in Laravel:

use App\Jobs\SyncData;

SyncData::dispatch($payload);

// or the helper form
dispatch(new App\Jobs\ProcessUpload($file));

And the job itself is a plain Laravel job. Here is a lightly adapted version of the example from the NativePHP docs, imagining a PHP Architect companion app syncing reading progress in the background:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use NativePHP\Plugins\Dialog\Dialog;

class SyncData implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(public array $payload) {}

    public function handle(): void
    {
        Http::post('https://api.phparch.com/sync', $this->payload);

        Dialog::toast('Sync complete!');
    }
}

A few things are worth calling out. The worker requires ZTS PHP, which ships by default in v3.1 and later. Only the database queue connection is supported, and it uses the same SQLite database your app already relies on. Because jobs are persisted to that database, they survive app restarts, and if a job fails, Laravel’s normal retry and failure handling applies. In other words, it is the queue system you already know, running natively on a device.

Plenty more landed alongside it

The v3.0 release rebuilt the framework around a plugin architecture, where all the core device APIs (Camera, Biometrics, Dialog, Geolocation, Scanner, and more) are shipped as individual plugins you register through a NativeServiceProvider. The v3.1 line then piled on the runtime improvements plus some genuinely important reach changes: the minimum Android version dropped from Android 13 (API 33) down to Android 8 (API 26), which dramatically widens the pool of devices your app can run on, and iOS gained full ICU/Intl support so packages like Filament that depend on the intl extension now work on both platforms.

There is also PHP 8.3 through 8.5 support, with NativePHP reading your app’s PHP version from composer.json and matching it automatically. Push notification support arrived in the 3.2 series via APNS on iOS and FCM on Android. Development has stayed brisk, with point releases landing steadily through the spring, the most recent being 3.3.6 on June 5, 2026, and a v4 line already in beta.

Should you care?

If you tried NativePHP Mobile early and walked away because it felt sluggish, this is your cue to look again. The persistent runtime addresses the single most common complaint head-on, and the background queue worker unlocks a category of apps (sync-heavy, upload-heavy, anything with real work to do off-screen) that were genuinely painful before. For a Laravel developer, the pitch is now very hard to argue with: your existing skills, your existing framework, and performance that no longer apologizes for itself.

The wider point is that NativePHP is maturing fast. What started as a clever proof of concept is turning into a tool you can reasonably ship production apps with. If you have a side project that has always wanted to be a phone app, this is a good weekend to find out how far your Laravel knowledge carries you.

Sources