diff --git a/resources/views/docs/mobile/3/concepts/queues.md b/resources/views/docs/mobile/3/concepts/queues.md
new file mode 100644
index 00000000..67551806
--- /dev/null
+++ b/resources/views/docs/mobile/3/concepts/queues.md
@@ -0,0 +1,89 @@
+---
+title: Queues
+order: 250
+---
+
+## Background Queue Worker
+
+NativePHP runs a background queue worker alongside your app's main thread. Queued jobs execute off the main thread,
+so they won't block your UI or slow down user interactions.
+
+Both iOS and Android are supported.
+
+## Setup
+
+Set your queue connection to `database` in your `.env` file:
+
+```dotenv
+QUEUE_CONNECTION=database
+```
+
+That's it. NativePHP handles the rest — the worker starts automatically when your app boots.
+
+## Usage
+
+Use Laravel's standard queue dispatching. Everything works exactly as you'd expect:
+
+```php
+use App\Jobs\SyncData;
+
+SyncData::dispatch($payload);
+```
+
+Or using the `dispatch()` helper:
+
+```php
+dispatch(new App\Jobs\ProcessUpload($file));
+```
+
+### Example Job
+
+Here's a simple job that makes an API call in the background:
+
+```php
+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()
+ {
+ Http::post('https://api.example.com/sync', $this->payload);
+
+ Dialog::toast('Sync complete!');
+ }
+}
+```
+
+## How It Works
+
+When your app boots, NativePHP automatically starts a dedicated PHP runtime on a separate thread. This worker
+polls `queue:work --once` in a loop, picking up and executing queued jobs as they come in.
+
+Because it runs on its own thread with its own PHP runtime, your queued jobs are fully isolated from the main
+request cycle — long-running tasks won't affect app responsiveness.
+
+
+
+## Things to Note
+
+- The queue worker requires [ZTS (Thread-Safe) PHP](/docs/mobile/3/getting-started/changelog), which is included by default in v3.1+.
+- Only the `database` queue connection is supported. This uses the same SQLite database as your app.
+- Jobs are persisted to the database, so they survive app restarts.
+- If a job fails, Laravel's standard retry and failure handling applies.
\ No newline at end of file
diff --git a/resources/views/docs/mobile/3/getting-started/changelog.md b/resources/views/docs/mobile/3/getting-started/changelog.md
index b5a1ff37..ba5a4d78 100644
--- a/resources/views/docs/mobile/3/getting-started/changelog.md
+++ b/resources/views/docs/mobile/3/getting-started/changelog.md
@@ -3,4 +3,40 @@ title: Changelog
order: 2
---
-For changes prior to v3, see the [v2 documentation](/docs/mobile/2/getting-started/changelog).
\ No newline at end of file
+For changes prior to v3, see the [v2 documentation](/docs/mobile/2/getting-started/changelog).
+
+## v3.1 — Persistent Runtime & Performance
+
+### New Features
+
+- **Persistent PHP Runtime** — Laravel boots once and the kernel is reused across requests, yielding ~5-30ms response times vs ~200-300ms previously.
+- **ZTS (Thread-Safe) PHP** support enabling background queue workers
+- **PHP Queue Worker** — a dedicated background thread runs queued Laravel jobs off the main thread on both iOS and Android. Just set `QUEUE_CONNECTION=database` and dispatch jobs as normal. See [Queues](../concepts/queues) for details.
+- **Binary caching** — PHP binaries are cached in `nativephp/binaries` to avoid re-downloading on every build
+- **Versions manifest** — binary URLs fetched from `versions.json` instead of being hardcoded
+- **Android 8+ support** — minimum SDK lowered from Android 13 (API 33) to Android 8 (API 26), dramatically expanding device reach
+- **PHP 8.3–8.5 support** — NativePHP now detects your app's PHP version from `composer.json` and matches it automatically, with PHP 8.3 as the lowest supported version
+- **ICU/Intl support on iOS** — iOS now ships with full ICU support, enabling Filament and other packages that depend on the `intl` extension to work on both platforms
+- **Configurable Android SDK versions** — `compile_sdk`, `min_sdk`, and `target_sdk` in your config
+- **Plugin multi-register** — `native:plugin:register` discovers and registers multiple plugins in one pass
+- **Unregistered plugin warnings** during `native:run`
+- **`ios/i` and `android/a` flags** for the `native:jump` command
+
+### Improvements
+
+- Static linking on Android for better performance and reliability
+- Plugin compilation during `native:package` builds
+- URL encoding preserved on Android redirects
+- Removed unused `react/http` and `react/socket` dependencies
+
+### Developer Experience
+
+- Laravel Boost skill support (shoutout Pushpak!) LINK TO PRS
+
+## v3.0 — Plugin Architecture
+
+- **Plugin-based architecture** — the framework is built around a modular plugin system
+- **All core APIs shipped as plugins** — Camera, Biometrics, Dialog, and more are all individual plugins
+- **`NativeServiceProvider`** for registering third-party plugins
+- **Plugin management commands** — install, register, and manage plugins from the CLI
+- **Free and open source**
diff --git a/resources/views/docs/mobile/3/getting-started/commands.md b/resources/views/docs/mobile/3/getting-started/commands.md
index bc523e56..e500c222 100644
--- a/resources/views/docs/mobile/3/getting-started/commands.md
+++ b/resources/views/docs/mobile/3/getting-started/commands.md
@@ -32,15 +32,22 @@ Build and run your app on a device or simulator.
php artisan native:run {os?} {udid?}
```
-| Option | Description |
-|--------|-------------|
-| `os` | Target platform: `ios` or `android` |
-| `udid` | Specific device/simulator UDID |
-| `--build=debug` | Build type: `debug`, `release`, or `bundle` |
-| `--watch` | Enable hot reloading during development |
-| `--start-url=` | Initial URL/path to load (e.g., `/dashboard`) |
+| Option | Description |
+|--------|---------------------------------------------------|
+| `os` | Target platform: `ios/i` or `android/a` |
+| `udid` | Specific device/simulator UDID |
+| `--build=debug` | Build type: `debug`, `release`, or `bundle` |
+| `--watch` | Enable hot reloading during development |
+| `--start-url=` | Initial URL/path to load (e.g., `/dashboard`) |
| `--no-tty` | Disable TTY mode for non-interactive environments |
+
+
### native:watch
Watch for file changes and sync to a running mobile app.
@@ -49,10 +56,10 @@ Watch for file changes and sync to a running mobile app.
php artisan native:watch {platform?} {target?}
```
-| Option | Description |
-|--------|-------------|
-| `platform` | Target platform: `ios` or `android` |
-| `target` | The device/simulator UDID to watch |
+| Option | Description |
+|--------|-----------------------------------------|
+| `platform` | Target platform: `ios/i` or `android/a` |
+| `target` | The device/simulator UDID to watch |
### native:jump
@@ -62,14 +69,16 @@ Start the NativePHP development server for testing mobile apps without building.
php artisan native:jump
```
-| Option | Description |
-|--------|-------------|
-| `--platform=` | Target platform: `android` or `ios` |
-| `--host=0.0.0.0` | Host address to serve on |
-| `--http-port=` | HTTP port to serve on |
+| Option | Description |
+|-----------------------|-------------|
+| `--platform=` | Target platform: `android` or `ios` |
+| `ios/i` | Shorthand for `--platform=ios` |
+| `android/a` | Shorthand for `--platform=android` |
+| `--host=0.0.0.0` | Host address to serve on |
+| `--http-port=` | HTTP port to serve on |
| `--laravel-port=8000` | Laravel dev server port to proxy to |
-| `--no-mdns` | Disable mDNS service advertisement |
-| `--skip-build` | Skip building if `app.zip` exists |
+| `--no-mdns` | Disable mDNS service advertisement |
+| `--skip-build` | Skip building if `app.zip` exists |
### native:open
@@ -79,9 +88,9 @@ Open the native project in Xcode or Android Studio.
php artisan native:open {os?}
```
-| Option | Description |
-|--------|-------------|
-| `os` | Target platform: `ios` or `android` |
+| Option | Description |
+|--------|-----------------------------------------|
+| `os` | Target platform: `ios/i` or `android/a` |
### native:tail
@@ -119,12 +128,12 @@ Package your app for distribution with signing.
php artisan native:package {platform}
```
-| Option | Description |
-|--------|-------------|
-| `platform` | Target platform: `android` or `ios` |
-| `--build-type=release` | Build type: `release` or `bundle` |
-| `--output=` | Output directory for signed artifacts |
-| `--jump-by=` | Skip ahead in version numbering |
+| Option | Description |
+|--------|---------------------------------------------------|
+| `platform` | Target platform: `android/a` or `ios/i` |
+| `--build-type=release` | Build type: `release` or `bundle` |
+| `--output=` | Output directory for signed artifacts |
+| `--jump-by=` | Skip ahead in version numbering |
| `--no-tty` | Disable TTY mode for non-interactive environments |
**Android Options:**
@@ -181,10 +190,10 @@ Generate signing credentials for iOS and Android.
php artisan native:credentials {platform?}
```
-| Option | Description |
-|--------|-------------|
-| `platform` | Target platform: `android`, `ios`, or `both` |
-| `--reset` | Generate new keystore and PEM certificate |
+| Option | Description |
+|--------|--------------------------------------------------|
+| `platform` | Target platform: `android/a`, `ios/i`, or `both` |
+| `--reset` | Generate new keystore and PEM certificate |
### native:check-build-number
@@ -219,15 +228,15 @@ php artisan native:plugin:list
### native:plugin:register
-Register a plugin in your NativeServiceProvider.
+Register a plugin in your NativeServiceProvider. When called without arguments, discovers all unregistered plugins and lets you register them.
```shell
-php artisan native:plugin:register {plugin}
+php artisan native:plugin:register {plugin?}
```
| Option | Description |
|--------|-------------|
-| `plugin` | Package name (e.g., `vendor/plugin-name`) |
+| `plugin` | Package name (e.g., `vendor/plugin-name`). Optional — omit to discover unregistered plugins |
| `--remove` | Remove the plugin instead of adding it |
| `--force` | Skip conflict warnings |
diff --git a/resources/views/docs/mobile/3/getting-started/configuration.md b/resources/views/docs/mobile/3/getting-started/configuration.md
index 5b8eae02..6481e0b5 100644
--- a/resources/views/docs/mobile/3/getting-started/configuration.md
+++ b/resources/views/docs/mobile/3/getting-started/configuration.md
@@ -56,78 +56,68 @@ Note that this will make your application's boot up slightly slower as it must u
But this ensures that you can iterate quickly during development, while providing a faster, more stable experience for
end users once an app is published.
-## Cleanup `env` keys
+## Persistent Runtime
-The `cleanup_env_keys` array in the config file allows you to specify keys that should be removed from the `.env` file
-before bundling. This is useful for removing sensitive information like API keys or other secrets.
+v3.1 introduces a persistent PHP runtime that boots Laravel once and reuses the kernel across all subsequent requests.
+This dramatically improves performance — from ~200-300ms per request down to ~5-30ms.
-## Cleanup `exclude_files`
+The `runtime` section controls this behavior:
-The `cleanup_exclude_files` array in the config file allows you to specify files and folders that should be removed
-before bundling. This is useful for removing files like logs or other temporary files that aren't required for your app
-to function and bloat your downloads.
+```php
+'runtime' => [
+ 'mode' => env('NATIVEPHP_RUNTIME_MODE', 'persistent'), // [tl! highlight]
+ 'reset_instances' => true,
+ 'gc_between_dispatches' => false,
+],
+```
-## Permissions
-In general, the app stores don't want your app to have permissions (a.k.a entitlements) it doesn't need.
+- `mode` — Set to `persistent` (default) to reuse the Laravel kernel, or `classic` to boot/shutdown per request.
+ If persistent boot fails, it falls back to classic mode automatically.
+- `reset_instances` — Whether to clear resolved facade instances between dispatches. (default: `true`)
+- `gc_between_dispatches` — Whether to run garbage collection between dispatches. Enable this if you notice memory
+ growth over time. (default: `false`)
-By default, all optional permissions are disabled.
+
+
+## Deep Links
+
+Configure deep linking to allow URLs to open your app directly:
```php
- 'permissions' => [
- 'biometric' => false,
- 'camera' => false,
- 'location' => false,
- 'microphone' => false,
- 'microphone_background' => false,
- 'network_state' => true,
- 'nfc' => false,
- 'push_notifications' => false,
- 'storage_read' => false,
- 'storage_write' => false,
- 'scanner' => false,
- 'vibrate' => false,
- ],
+'deeplink_scheme' => env('NATIVEPHP_DEEPLINK_SCHEME'),
+'deeplink_host' => env('NATIVEPHP_DEEPLINK_HOST'),
```
-For iOS, this will provide a sensible default description.
+The `deeplink_scheme` enables custom URL schemes (e.g. `myapp://some/path`), while `deeplink_host` enables
+verified HTTPS links and NFC tags (e.g. `https://your-host.com/path`).
-### Custom permission descriptions
+See the [Deep Links](../concepts/deep-links) documentation for full details.
-For iOS, it's possible to define custom permission descriptions. In most cases, you are required to provide clear
-reasons why your app needs certain permissions. You can do this easily from the config file:
+## Start URL
+
+Set the initial path that loads when your app starts:
```php
- 'permissions' => [
- 'biometric' => 'Access to the biometric sensor is needed to secure user resources',
- //...
- ],
+'start_url' => env('NATIVEPHP_START_URL', '/'),
```
-### Available permissions
-
-- `biometric` - Allows your application to use fingerprint or face-recognition hardware (with a fallback to PIN code)
- to secure parts of your application.
-- `camera` - Allows your application to request access to the device's camera, if present. Required for taking photos and
- recording video. Note that the user may deny access and any camera functions will then result in a no-op.
-- `nfc` - Allows your application to request access to the device's NFC reader, if present.
-- `push_notifications` - Allows your application to request permissions to send push notifications. Note that the user
- may deny this and any push notification functions will then result in a no-op.
-- `location` - Allows your application to request access to the device's GPS receiver, if present. Note that the user
- may deny this and any location functions will then result in a no-op.
-- `vibrate` - In modern Android devices this is a requirement for most haptic feedback.
-- `storage_read` - Grants your app access to read from device storage locations. This is not required for basic app file manipulation.
-- `storage_write` - Allows your app to write to device storage. This is not required for basic app file manipulation.
-- `microphone` - Allows your application to request access to the device's microphone, if present. Required for audio
- recording functionality. Note that the user may deny access and any microphone functions will then result in a no-op.
-- `microphone_background` - Allows your application to request access to the device's microphone, if present. Required
- for audio recording functionality. Note that the user may deny access and any microphone functions will then result in
- a no-op.
-- `scanner` - Allows your application to scan QR codes and barcodes. Note that the user may deny camera access and any
- scanning functions will then result in a no-op.
-- `network_state` - Allows your application to access information about the device's network connectivity status. This
- permission is enabled by default as it's commonly needed for basic network state detection.
+This is useful if you want to land users on a specific page like `/dashboard` or `/onboarding` instead of the root.
+
+## Cleanup `env` keys
+
+The `cleanup_env_keys` array in the config file allows you to specify keys that should be removed from the `.env` file
+before bundling. This is useful for removing sensitive information like API keys or other secrets.
+
+## Cleanup `exclude_files`
+
+The `cleanup_exclude_files` array in the config file allows you to specify files and folders that should be removed
+before bundling. This is useful for removing files like logs or other temporary files that aren't required for your app
+to function and bloat your downloads.
## Orientation
@@ -173,3 +163,155 @@ Once you've published an app with iPad support, it cannot be undone. If you wish
will need to change your `NATIVEPHP_APP_ID` and publish the app under a new App Store listing.
+
+## Android SDK Versions
+
+The `android` section of your config file lets you control which Android SDK versions are used when building your app.
+These are nested under the `android` key in `config/nativephp.php`:
+
+```php
+'android' => [
+ 'compile_sdk' => env('NATIVEPHP_ANDROID_COMPILE_SDK', 36),
+ 'min_sdk' => env('NATIVEPHP_ANDROID_MIN_SDK', 33),
+ 'target_sdk' => env('NATIVEPHP_ANDROID_TARGET_SDK', 36),
+],
+```
+
+- `compile_sdk` - The SDK version used to compile your app. This determines which Android APIs are available to you
+ at build time. (default: `36`)
+- `min_sdk` - The minimum Android version your app supports. Devices running an older version won't be able to install
+ your app. (default: `26`, Android 8)
+- `target_sdk` - The SDK version your app is designed and tested against. Google Play uses this to apply appropriate
+ compatibility behaviors. (default: `36`)
+
+You can also set these via environment variables:
+
+```dotenv
+NATIVEPHP_ANDROID_COMPILE_SDK=36
+NATIVEPHP_ANDROID_MIN_SDK=26
+NATIVEPHP_ANDROID_TARGET_SDK=36
+```
+
+
+
+## Android Build Configuration
+
+Fine-tune your Android build process with these options under the `android.build` key:
+
+```php
+'android' => [
+ 'build' => [
+ 'minify_enabled' => env('NATIVEPHP_ANDROID_MINIFY_ENABLED', false),
+ 'shrink_resources' => env('NATIVEPHP_ANDROID_SHRINK_RESOURCES', false),
+ 'obfuscate' => env('NATIVEPHP_ANDROID_OBFUSCATE', false),
+ 'debug_symbols' => env('NATIVEPHP_ANDROID_DEBUG_SYMBOLS', 'FULL'),
+ 'parallel_builds' => env('NATIVEPHP_ANDROID_PARALLEL_BUILDS', true),
+ 'incremental_builds' => env('NATIVEPHP_ANDROID_INCREMENTAL_BUILDS', true),
+ ],
+],
+```
+
+- `minify_enabled` — Enable R8/ProGuard code shrinking. (default: `false`)
+- `shrink_resources` — Remove unused resources from the APK. (default: `false`)
+- `obfuscate` — Obfuscate class and method names. (default: `false`)
+- `debug_symbols` — Include debug symbols. Set to `FULL` for symbolicated crash reports. (default: `FULL`)
+- `parallel_builds` / `incremental_builds` — Gradle build performance options. (default: `true`)
+
+
+
+## Android Status Bar Style
+
+Control the color of the status bar and navigation bar icons:
+
+```php
+'android' => [
+ 'status_bar_style' => env('NATIVEPHP_ANDROID_STATUS_BAR_STYLE', 'auto'),
+],
+```
+
+Options: `auto` (detect from system theme), `light` (white icons), or `dark` (dark icons).
+
+## Development Server
+
+Configure the development server used by `native:jump` and `native:watch`:
+
+```php
+'server' => [
+ 'http_port' => env('NATIVEPHP_HTTP_PORT', 3000),
+ 'ws_port' => env('NATIVEPHP_WS_PORT', 8081),
+ 'service_name' => env('NATIVEPHP_SERVICE_NAME', 'NativePHP Server'),
+ 'open_browser' => env('NATIVEPHP_OPEN_BROWSER', true),
+],
+```
+
+- `http_port` — The port for serving your app during development. (default: `3000`)
+- `ws_port` — The WebSocket port for hot reload communication. (default: `8081`)
+- `service_name` — The mDNS service name advertised on your network. (default: `NativePHP Server`)
+- `open_browser` — Automatically open a browser with a QR code when the server starts. (default: `true`)
+
+## Hot Reload
+
+Customize which files trigger hot reloads during development:
+
+```php
+'hot_reload' => [
+ 'watch_paths' => [
+ 'app',
+ 'resources',
+ 'routes',
+ 'config',
+ 'public',
+ ],
+ 'exclude_patterns' => [
+ '\.git',
+ 'storage',
+ 'node_modules',
+ ],
+],
+```
+
+## Development Team (iOS)
+
+Set your Apple Developer Team ID for code signing:
+
+```php
+'development_team' => env('NATIVEPHP_DEVELOPMENT_TEAM'),
+```
+
+This is typically detected from your installed certificates, but you can override it here. Find your Team ID
+in your Apple Developer account under Membership details.
+
+## App Store Connect
+
+Configure automated iOS uploads with the App Store Connect API:
+
+```php
+'app_store_connect' => [
+ 'api_key' => env('APP_STORE_API_KEY'),
+ 'api_key_id' => env('APP_STORE_API_KEY_ID'),
+ 'api_issuer_id' => env('APP_STORE_API_ISSUER_ID'),
+ 'app_name' => env('APP_STORE_APP_NAME'),
+],
+```
+
+These credentials are used by `native:package --upload-to-app-store` to upload your IPA directly to
+App Store Connect without opening Xcode.
+
+
diff --git a/resources/views/docs/mobile/3/getting-started/environment-setup.md b/resources/views/docs/mobile/3/getting-started/environment-setup.md
index 59188752..1847e743 100644
--- a/resources/views/docs/mobile/3/getting-started/environment-setup.md
+++ b/resources/views/docs/mobile/3/getting-started/environment-setup.md
@@ -67,7 +67,7 @@ to develop and test your apps on a Simulator. However, you will need to enroll w
## Android Requirements
1. [Android Studio 2024.2.1 or later](https://developer.android.com/studio)
-2. Android SDK with API 33 or higher
+2. Android SDK with API 29 or higher
3. **Windows only**: You must have [7zip](https://www.7-zip.org/) installed.
+## WebView Compatibility
+
+On Android, the web view is powered by the system's built-in WebView component, which varies by device and OS version.
+Older Android versions ship with older WebView engines that may not support modern CSS features.
+
+For example, Tailwind CSS v4 uses `@theme` and other newer CSS features that are not supported on older WebView
+versions. If you are targeting a lower `min_sdk` to support older devices, consider using Tailwind CSS v3 or another
+CSS framework that generates compatible output. You can configure your minimum SDK version in your
+[Android SDK Versions](/docs/mobile/3/getting-started/configuration#android-sdk-versions) settings.
+
+Always test your app on emulators running your minimum supported Android version to catch these issues early. You can
+create emulators for older API levels in Android Studio's Virtual Device Manager.
+
With just a few small changes, we've been able to define a layout that will work well on a multitude of devices
without having to add complex calculations or lots of device-specific CSS rules to our code.