Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Starter Desktop Flux Laravel Package

nativecli/starter-desktop-flux

A NativeCLI desktop starter kit for Laravel and NativePHP, preconfigured with Flux UI. It scaffolds a native desktop app with a ready-made UI foundation, routing, and build setup, helping you skip boilerplate and focus on features. Ideal for quickly bootstrapping cross-platform desktop projects.

View on GitHub
Deep Wiki
Context7

Getting Started

This is the NativePHP Desktop starter kit (nativecli/starter-desktop-flux) — a Laravel application scaffold that ships with NativePHP Desktop (nativephp/desktop) and Flux UI already wired up, so you get a real desktop window wrapping a Laravel app instead of a browser tab.

Install (v2.0.0):

laravel new my-desktop-app   # choose the NativePHP Desktop / Flux starter
cd my-desktop-app
composer install && npm install
php artisan native:install    # publishes native config, prepares the runtime

The release notes stress that laravel new is the intended install path — the starter kit is versioned in lockstep with NativePHP, so the scaffold (not composer require) is what pulls in a consistent set of dependencies.

Where to look first:

  1. composer.json — confirm nativephp/desktop: ^2.0. This is the whole point of 2.0.0.
  2. config/nativephp.php (published by native:install) — window size, app ID, tray/menu, updater.
  3. routes/web.php and resources/views/components/layouts/app.blade.php — your desktop "shell"; Flux components live in the Blade views.
  4. app/Providers/ — where starter kits typically register native menu/tray hooks.
  5. .env / config/database.php — the app is SQLite-first, local-only by default.

First use case: build a small local tool — a time tracker, invoice generator, or internal admin panel — that reads/writes SQLite and never touches the network. Run it with php artisan native:serve (dev window with hot reload), iterate with normal Laravel tooling, then php artisan native:build to produce a distributable for your current OS.

Implementation Patterns

Treat it as a normal Laravel app, then add native surface area. Controllers, form requests, policies, migrations, and Blade all behave identically. The desktop layer is a thin shell, so keep business logic in app/Actions or app/Services rather than in native event callbacks — that keeps everything testable and portable.

Layout and chrome. The starter's Blade layout is your window. Use Flux components for a native-feeling UI (toolbars, sidebars, modals) and drop the default web nav — desktop users expect a persistent sidebar or top bar, not a marketing header.

Native features behind an interface. Tray icons, notifications, clipboard, native dialogs, and file save dialogs are typically invoked through the Native facade. Wrap each call in a small service class so you can:

class Notifier
{
    public function ping(string $message): void
    {
        Native::notification()->title('My App')->message($message)->show();
    }
}

…and swap in a fake in tests instead of triggering real OS dialogs.

Local-first data. SQLite + seeders + a "reset/export my data" action is the dominant pattern. Add a Settings model backed by the DB (not .env) for user-tweakable preferences, since packaged apps shouldn't require editing env files.

Multi-window and deep links. If you need a second window (e.g. a quick-capture panel), define it in config/nativephp.php and open it from a Livewire/Alpine action. Persist window position/size to the DB so the app reopens where the user left it.

Dev-to-release workflow:

php artisan native:serve     # hot-reload dev window
npm run build                # production assets — do this BEFORE native:build
php artisan native:build     # platform binary

Build per-OS in CI (GitHub Actions matrix) with signing credentials injected as secrets. There is no cross-compilation — a macOS .dmg must be built on macOS.

Auto-updates. NativePHP's updater expects a versioned manifest at a URL you control plus a matching version string in your native config. Bump both in the same commit as your release tag, or clients will silently never update.

Gotchas and Tips

2.0.0 is a hard version alignment, not a feature drop. The starter jumps to nativephp/desktop:^2.0; v1 starters pair only with desktop v1. If you're upgrading an existing v1 project, don't just bump the constraint — the cleanest path is a fresh laravel new and porting your app/, resources/views, and database/ across, then re-testing every native feature (tray, menu, dialogs) because the underlying API surface changed between majors. Stay on the 1.x starter line if you can't migrate now.

Dependency bumps are security-only. The form-data 4.0.4 and Vite 6.4.0 bumps are transitive/dev-tooling fixes. If your app pins Vite independently, verify your build still produces assets under the desktop runtime before shipping — Vite major-adjacent bumps occasionally change asset paths that break the packaged webview.

Build assets or ship a blank window. Forgetting npm run build before native:build is the single most common "my app is white" bug — the packaged app serves static assets, not the Vite dev server. Check public/build/manifest.json exists in the built artifact.

Don't write to resources/ or base_path() at runtime. Packaged apps may be installed read-only (or in /Applications). Use storage_path() for anything mutable, and remember the SQLite file path shifts between dev and packaged builds — never hardcode database/database.sqlite.

Baked-in environment. Production builds embed configuration at build time. Never ship a build containing your dev .env with API keys; use a build-time env step and keep secrets server-side (or out entirely for a local-first app).

No cron, no queue workers. There's no long-running server. schedule:run won't fire on its own; use native timers/window events, or run a lightweight loop while the window is open. Similarly, QUEUE_CONNECTION=database jobs need a manual drain — prefer synchronous dispatch for desktop workloads.

Debugging: the window is a webview, so enable devtools in dev builds and watch both the native process stdout and storage/logs/laravel.log. A blank window is almost always an asset path issue; a crash-on-launch is usually a missing/invalid app ID or bundle identifier in config/nativephp.php.

Signing is the release bottleneck. Budget time for macOS notarization (notarytool credentials) and Windows code signing certificates. Unsigned macOS builds are quarantined by Gatekeeper — users will see "damaged app" errors that look like your bug but aren't.

Extension points worth knowing: publish and edit the NativePHP config to customize menus/tray/shortcuts, register custom window state persistence, and hook app lifecycle events (window close, app suspend) for autosave. Those three cover most desktop UX expectations and are far easier than fighting the shell later.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource