How NativePHP Bridges Laravel and Electron for Seamless Desktop Apps

This article explains how NativePHP integrates Laravel with Electron (and future Tauri) by providing a complete API, detailing installation, the boot process, core workflow involving Express and PHP servers, event handling, window management, and the benefits of using a unified backend‑centric approach.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
How NativePHP Bridges Laravel and Electron for Seamless Desktop Apps

Overview

NativePHP supplies a Laravel‑friendly API layer that lets a Laravel application control a desktop runtime (currently Electron, with future Tauri support). It handles packaging, starts required server processes, and forwards events between the PHP and JavaScript environments.

Installation

$ composer require nativephp/electron

$ php artisan native:install   # installs Node dependencies
$ php artisan native:serve      # launches the native Electron app

The native:install command runs npm/yarn install inside the resources/js folder. The native:serve command starts the Electron‑based application.

Booting the Native App

native:serve

is a standard Laravel Artisan command. It changes the working directory to resources/js and executes yarn run dev, which starts the Electron process via electron‑vite.

NativePHP boot sequence
NativePHP boot sequence

Frontend Build (electron‑vite)

The resources/js directory is a standard Vite‑based Electron project. Its package.json scripts are:

"scripts": {
  "start": "electron-vite preview",
  "dev": "electron-vite dev --watch",
  "build": "electron-vite build"
}

The entry file main/index.js loads the nativephp-electron plugin, which starts the NativePHP runtime.

Electron Vite entry point
Electron Vite entry point

Core Workflow

Start an Express API server that exposes REST endpoints for window, menu, and clipboard control.

Launch a lightweight PHP built‑in server with php -S 127.0.0.1:<port> to serve the Laravel application.

Run Laravel migrations, WebSocket server, and queue workers via artisan.

Start scheduled tasks defined in Laravel.

Emit a “Booted” notification to signal that the native environment is ready.

Register event listeners that forward Electron events to Laravel.

Add a termination handler that kills all child processes when the app closes.

Express API Server

The Express server provides endpoints that Laravel facades call. For example, the Window facade sends a POST request to the Express server, which then creates or resizes an Electron BrowserWindow:

use Native\Laravel\Facades\Window;

Window::open()->width(800)->height(800);

Corresponding Electron code:

const window = new BrowserWindow({
  width: windowState?.width || parseInt(width),
  height: windowState?.height || parseInt(height),
});
Express API handling window resize
Express API handling window resize

PHP Built‑in Server

After the Express server is up, the plugin runs a command similar to:

php -S 127.0.0.1:$phpPort

Each server runs in its own process; the plugin tracks their PIDs so they can be terminated together when the Electron window closes. No external process manager (e.g., Supervisor) is used, so developers should monitor for unexpected exits.

Event Listeners

When both servers are running, the plugin registers listeners that forward Electron events to Laravel via the _native/api/events endpoint.

window.on('resized', () => {
  notifyLaravel('_native/api/events', {
    event: 'Native\\Laravel\\Events\\Windows\\WindowResized',
    payload: [id, window.getSize()[0], window.getSize()[1]]
  })
});

Laravel receives the POST request and dispatches the event:

Route::post('_native/api/events', DispatchEventFromAppController::class);

class DispatchEventFromAppController {
    public function __invoke(Request $request) {
        $event = $request->get('event');
        if (class_exists($event)) {
            $event = new $event(...$request->get('payload', []));
            event($event);
        }
        return response()->json(['success' => true]);
    }
}

Opening Windows

The default window is defined in NativeAppServiceProvider. Developers can change the URL, size, or other options:

Window::open()
    ->url(url('/login'))
    ->width(800)
    ->height(400);
Custom window configuration
Custom window configuration

Why Use NativePHP?

NativePHP abstracts the differences between Electron, Tauri, and other desktop runtimes, exposing a unified Laravel API. Developers can manipulate native windows, menus, clipboard, and other OS features directly from PHP without writing JavaScript. The same API can later target other frameworks (e.g., Symfony) or other runtimes, providing a portable bridge between PHP back‑ends and native desktop front‑ends.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptElectronPHPLaravelDesktop AppsNativePHP
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.