Composer And Ecosystem

NativePHP Desktop And Mobile Orientation

NativePHP lets PHP developers build installable desktop and mobile applications using PHP, Laravel, web technologies, and bridges to operating-system features. It packages a PHP runtime with the application so the end user does not need to install PHP or run a separate web server.

This is a different deployment model from hosting Laravel on a server. The application code and runtime live on the user's device, releases must be built for target platforms, local data needs a migration strategy, and secrets shipped with the application cannot be treated as server secrets.

NativePHP is an ecosystem choice rather than a PHP language feature. Its APIs, version requirements, supported native capabilities, and publishing workflow can change. Check the official documentation for the exact Desktop or Mobile version selected by a project before installation.

Desktop And Mobile Are Distinct Products

NativePHP documentation currently presents separate Desktop and Mobile product lines. They share the goal of using PHP and Laravel skills for installed applications, but their runtimes and platform concerns differ.

NativePHP for Desktop uses a bundled PHP runtime with an Electron-based desktop shell. The official Desktop v2 documentation describes window and menu management, dialogs, notifications, clipboard access, global hotkeys, local databases, queues, files, child processes, building, signing, publishing, and updates.

NativePHP for Mobile embeds a precompiled PHP runtime in a Swift or Kotlin shell and bridges PHP to mobile APIs. The official Mobile v3 documentation covers web views and native components, events, app assets, deep links, push notifications, databases, queues, authentication, permissions, and plugins for capabilities such as camera, biometrics, geolocation, secure storage, and sharing.

Do not assume an API shown in Desktop documentation exists on Mobile, or that a Mobile plugin is part of Desktop. Choose the product and version first, then design against that documentation.

What Runs On The User's Device

A traditional Laravel application commonly receives HTTP requests on infrastructure controlled by the team. A NativePHP application packages application code, dependencies, assets, and a PHP runtime for execution on the user's machine or phone.

The user interface may still be built with Blade, Livewire, Inertia, Vue, React, plain HTML, CSS, and JavaScript. "Native" does not mean every screen is automatically a platform-native widget. It means the application is installed, the PHP runtime executes on-device, and supported bridges can access host capabilities. Mobile also offers documented native-component options in addition to web-view UI.

This model is useful for applications that need local files, offline behavior, desktop windows, device APIs, or an installable user experience. It does not eliminate the need for a backend when users share data, authenticate centrally, receive server events, or need authoritative remote processing.

Keep Domain Code Independent Of The Host Bridge

Native APIs should stay near an infrastructure boundary. Core calculations and business rules should not call a notification, clipboard, camera, or window facade directly.

PHP example
<?php

declare(strict_types=1);

interface UserNotifier
{
    public function notify(string $title, string $body): void;
}

final class CompleteImport
{
    public function __construct(private UserNotifier $notifier)
    {
    }

    public function handle(int $importedRows): string
    {
        $message = $importedRows . ' rows imported';
        $this->notifier->notify('Import complete', $message);

        return $message;
    }
}

final class RecordingNotifier implements UserNotifier
{
    /** @var list<string> */
    public array $messages = [];

    public function notify(string $title, string $body): void
    {
        $this->messages[] = $title . ': ' . $body;
    }
}

$notifier = new RecordingNotifier();
$result = (new CompleteImport($notifier))->handle(250);

echo $result . PHP_EOL;
echo $notifier->messages[0] . PHP_EOL;

// Prints:
// 250 rows imported
// Import complete: 250 rows imported

A NativePHP adapter can implement UserNotifier with the product's current notification API. Tests use the recording implementation without launching the desktop or mobile shell. This separation also makes it possible to reuse the domain service in a web or command-line application.

Desktop Installation Is A Toolchain Decision

At the time this lesson was reviewed, the official Desktop v2 installation page listed PHP 8.3 or later, Laravel 11 or later, Node 22 or later, and Windows 10 or later, macOS 12 or later, or Linux for development. These requirements are version-specific and must be rechecked before starting a project.

The documented Desktop v2 setup flow is:

composer require nativephp/desktop
php artisan native:install
php artisan native:run

The installer publishes configuration and prepares Electron dependencies. The documentation recommends getting the Laravel application working in a browser before running it in the native context, because ordinary exceptions are easier to isolate there.

Native desktop development interacts with host GUI tooling, Node, platform build tools, and signing credentials. Containers or virtualized environments may add manual steps. A team should prove the development and CI workflow on every supported operating system before committing to a release date.

Local Data And Application Paths

Installed applications cannot assume a server-style writable project directory. Operating systems provide application-data, cache, documents, temporary, and log locations with different lifecycle and backup behavior. Use NativePHP's documented path and file facilities for the selected version rather than hard-coded home-directory strings.

SQLite is a natural fit for local structured data. It supports offline use and ships as one database file, but the application still needs schema migrations, backups where appropriate, corruption recovery, and upgrade testing.

Separate durable user data from disposable cache data. Removing a cache should not delete documents or unsynchronized work. Uninstall behavior also differs by platform, so document what remains on disk and how users export important data.

Offline-First Is More Than Local Storage

An application is not offline-first merely because it opens without a network. Every feature needs a defined offline state:

  • which reads use local data
  • which commands can be queued
  • how pending work is displayed
  • when synchronization retries
  • how duplicate submissions are prevented
  • how conflicts are detected and resolved
  • what happens when authentication expires
  • which operations must remain online

Give locally created records stable identifiers before synchronization. Make remote commands idempotent. Store sync status and last error rather than discarding failed work.

PHP example
<?php

declare(strict_types=1);

final readonly class PendingChange
{
    public function __construct(
        public string $operationId,
        public string $recordId,
        public string $action,
        public array $payload,
        public DateTimeImmutable $createdAt,
    ) {
    }
}

$change = new PendingChange(
    operationId: 'op-2f39',
    recordId: 'note-local-1042',
    action: 'note.updated',
    payload: ['title' => 'Deployment checklist'],
    createdAt: new DateTimeImmutable('2026-06-10T09:00:00Z'),
);

echo $change->operationId . ': ' . $change->action . PHP_EOL;

// Prints:
// op-2f39: note.updated

The operation ID lets a server recognize a retry. The record ID links later changes to the same local item. A real sync queue also needs attempts, next retry time, completion state, and a conflict policy.

Device And Operating-System Permissions

Desktop and mobile applications operate under host permissions. Camera, microphone, location, notifications, filesystem access, accessibility features, and global shortcuts may require declarations, user consent, or platform review.

Request the minimum permission at the moment it is needed. Explain why the feature needs it and handle denial as a normal state. A user may revoke permission after granting it.

Mobile store review and operating-system sandboxing can reject behavior that worked in development. Desktop antivirus, Gatekeeper, SmartScreen, or enterprise policy can block unsigned or suspicious builds. Test realistic installed builds, not only development mode.

Security Changes When Code Is Shipped

Anything packaged in a client application can be inspected by a determined user. Never ship database passwords, private API keys, signing keys, unrestricted cloud credentials, or a Laravel APP_KEY that protects server data elsewhere.

Use a backend to hold authoritative secrets and perform privileged actions. Give the installed application short-lived, user-scoped credentials. On mobile, use the documented secure-storage capability for tokens that must remain on-device; on desktop, evaluate the operating system's credential facilities and NativePHP's current support.

Treat web content as untrusted. Prevent cross-site scripting, validate deep links and file imports, restrict navigation to unexpected origins, and do not expose dangerous shell or filesystem operations to arbitrary JavaScript input.

A shell command bridge is particularly sensitive. Avoid building commands through string concatenation, allow only intended executables and arguments, and assume filenames can contain spaces or hostile characters.

Updates And Database Migrations

A hosted web application updates when the server deploys. An installed application creates a population of users running different versions. Some devices stay offline, skip releases, or update months later.

Design migrations to upgrade from every supported old version, not only the immediately previous build. Back up or transactionally migrate valuable local data. Test interrupted migrations and disk-full conditions. Do not mark a migration complete before its work is durable.

Contracts with a backend must tolerate supported client versions. Monitor old-version usage and set a clear minimum version policy. When an update is mandatory for security, the application needs a safe user experience for downloading it without losing unsynchronized work.

Building, Signing, And Publishing Desktop Apps

The official Desktop v2 documentation uses this command for a production build:

php artisan native:build

Builds target a platform and architecture, package the Laravel application with the Electron and PHP runtimes, and may require separate builds and tests for Windows, macOS, and Linux. Cross-compilation support is limited by the host and target combination.

Public Windows and macOS distribution requires code-signing work. macOS distribution commonly also requires notarization. Signing credentials belong in protected CI secrets, not the repository or packaged application.

Version the application deliberately. Test installation over a previous release, first launch, migration, update, rollback limitations, and clean installation. A build that starts on the developer's machine is not yet a releasable artifact.

Mobile Builds Have Store Constraints

Mobile development adds iOS and Android toolchains, application identifiers, signing identities, provisioning, permission manifests, icons, splash screens, device testing, and store submissions. Plugins may require native dependencies and platform-specific configuration.

Test on real devices as well as simulators. Camera, push notifications, background execution, biometric prompts, deep links, keyboard behavior, memory pressure, and network transitions can differ substantially from a desktop browser.

A single PHP codebase reduces duplicated application logic, but it does not remove platform product work. Teams still need to design for screen sizes, accessibility, navigation conventions, permission expectations, and store policy.

Testing Strategy

Keep most tests in ordinary PHP and Laravel layers. Domain services, validation, repositories, sync decisions, and conflict resolution should run without a native window.

Add adapter tests for NativePHP APIs and a smaller installed-application suite for:

  • window or navigation lifecycle
  • files and application paths
  • local database creation and migration
  • notification and permission behavior
  • background jobs and queues
  • offline startup and reconnection
  • update from an older release
  • signing and installation on each target platform

The official Desktop documentation includes testing guidance for features such as windows, shortcuts, shell access, child processes, and queue workers. Use the documentation for the exact installed version because test helpers and APIs can change.

When NativePHP Is A Good Fit

NativePHP is worth evaluating when a Laravel-skilled team needs an installable, cross-platform application and wants to share PHP domain logic with familiar web UI tools. Strong cases include local utilities, menubar tools, offline field applications, internal business software, file-processing tools, and products that need supported device APIs.

It may be a poor fit when the product needs a highly platform-specific native interface, relies on a native SDK without a maintained bridge, has strict binary-size constraints, or must use cutting-edge platform APIs immediately. A progressive web app, conventional hosted web app, Electron application using JavaScript, Flutter, React Native, Swift, Kotlin, or another toolkit may fit better.

Compare a proof of concept using the hardest requirement, not a hello-world screen. Test the real plugin, offline workflow, signing pipeline, performance, accessibility, and distribution path before choosing the architecture.

Keep Version Claims Checkable

Record the chosen NativePHP product, major version, Laravel version, PHP version, Node version, target operating systems, plugins, and build requirements in the project documentation. Link to the matching official documentation version.

Do not copy commands from an old blog post without checking the current docs. Desktop and Mobile have separate version histories. An example for Desktop v1, Desktop v2, Mobile v2, or Mobile v3 may be internally correct but wrong for another project.

Official starting points:

What You Should Be Able To Do

After this lesson, you should be able to explain how NativePHP packages PHP for installed desktop or mobile execution, distinguish the Desktop and Mobile products, and describe where web UI, Laravel code, the embedded runtime, and native bridges fit.

You should also be able to evaluate local storage, offline synchronization, permissions, shipped-code security, platform builds, signing, updates, migrations, and testing. The practical skill is choosing NativePHP with verified version requirements and a realistic release proof of concept, not assuming an existing Laravel website is automatically ready to ship as an installed application.

Practice

Practice: Decide If NativePHP Fits
  • an offline warehouse scanner using a camera and local queue
  • a public marketing website managed by editors
  • a macOS-only video editor requiring a new native media framework

Task

For each product, decide whether NativePHP is a strong candidate, possible with a proof of concept, or a poor default. Address Laravel skill reuse, offline needs, native API availability, platform specificity, distribution, and long-term maintenance.

Finish with the hardest proof-of-concept requirement you would test before approval.

Show solution

The offline warehouse scanner is a strong candidate for evaluation. It benefits from local data, queued synchronization, camera access, and reuse of Laravel domain code. The proof of concept must test the current Mobile camera or scanner plugin, poor-network behavior, duplicate-safe sync, device permissions, and Android/iOS release builds.

The public marketing website is a poor default for NativePHP. A hosted web application is easier for visitors to access, updates centrally, and fits editor workflows without app installation. NativePHP adds packaging and update work without a clear device capability requirement.

The macOS-only video editor is possible only after a demanding proof of concept and is likely better served by a platform-native stack. Its defining requirement is a new native media framework and intensive media processing. A maintained NativePHP bridge, performance, memory use, file access, and platform integration must be proved before choosing it.

The decisive test should target the hardest external constraint, not basic routing: real-device scanner reliability for the warehouse app and native media-framework integration plus representative export performance for the editor.

Practice: Design Offline Data And Sync

Design synchronization for a field-inspection application that creates reports and photos while offline.

Task

Specify:

  • local record and operation identifiers
  • durable storage locations for reports, photos, cache, and pending operations
  • idempotency behavior on the server
  • retry scheduling and user-visible status
  • conflict handling when the same report changes on two devices
  • authentication expiry while offline
  • cleanup after successful upload
  • recovery after an interrupted application update

Distinguish durable user data from disposable cache data.

Show solution

Create a UUID for every report, photo, and queued operation before network access. Store report metadata and queue state in SQLite. Store original photos in the application's durable documents/data location; thumbnails and resized upload previews may use a cache location because they can be regenerated.

Send the operation ID as an idempotency key. The server stores the completed result for that key so a retry cannot create a second report or photo. Queue records include attempt count, next-attempt time, last error, and states such as pending, syncing, conflict, and complete.

Use bounded exponential backoff with jitter and a manual retry action. Display unsynchronized and failed work clearly. If authentication expires, preserve queued work, pause remote attempts, and request login when the device reconnects.

Give reports a server revision. A rejected stale revision becomes a visible conflict; preserve both local and server values and require a documented merge or user decision. Do not silently overwrite inspection evidence.

Delete a durable original only after the server confirms it and retention policy allows removal. Updates must back up or transactionally migrate SQLite, leave photos untouched, and resume pending operations after restart.

Practice: Plan A Desktop Release

Prepare a release checklist for a NativePHP Desktop application targeting Windows and macOS.

Task

Cover:

  • pinned PHP, Laravel, Node, NativePHP, and package versions
  • clean dependency installation and frontend asset build
  • application version and local database migrations
  • platform and architecture builds
  • code signing and macOS notarization
  • secret handling in CI
  • installation, upgrade, and clean-install tests
  • offline startup and update recovery
  • rollback limitations and support diagnostics

State which checks must run on each target platform rather than only on Linux CI.

Show solution

Pin the supported PHP, Laravel, Node, NativePHP major version, Composer lock file, package-manager lock file, and build image. Start from a clean checkout, install production dependencies, run PHP tests and static analysis, compile frontend assets, and verify that no development secrets enter the artifact.

Set an application version that drives the documented migration/update behavior. Test local database upgrades from every supported old release and an interrupted migration using disposable copies of realistic data.

Build Windows and macOS artifacts on supported toolchains. Sign Windows output with protected credentials. Sign and notarize macOS output, then test the downloaded artifact on a machine that does not have the development environment.

Run clean install, in-place upgrade, first launch, offline launch, update check, failed update recovery, file access, notifications, menus, and application-data path tests on each target operating system and architecture. Linux-only CI cannot prove Gatekeeper, SmartScreen, platform paths, or native shell behavior.

Publish checksums and preserve symbols or logs needed for support. Document where logs and local data live, how users export data, minimum backend compatibility, and what rollback can do after a schema migration. Signing credentials remain in restricted CI storage and must never be packaged.