Skip to content
LibxaFrame
Sign In
v0.4.0: 12 August 2026

Your whole PHP stack,
in one window.

Libxa Desktop installs and supervises PHP, Node, Nginx, MySQL and phpMyAdmin, then serves every project on its own local domain. No separate setup, nothing added to your PATH.

Windows 10 / 11 · 64-bit · ~100 MB

Two things to know before installing

Builds are not code-signed yet, so Windows shows “Windows protected your PC” the first time: More info → Run anyway. And automatic runtime installation is Windows-only; on macOS and Linux the app detects what your package manager installed but cannot fetch runtimes itself.

What it does

From an empty machine to a served site.

Everything below works on a computer with nothing installed on it.

Installs what you are missing

Nginx, MariaDB, PHP and Node download from each publisher’s own host and are verified against a SHA-256 before anything is extracted. A mismatch deletes the file and stops. Nothing touches system directories or your PATH.

Every PHP version, side by side

Install 8.0 through 8.5 and switch the active one with a click. Each site is routed to its own version by a php-cgi process per version: a legacy project on 8.1 and a new one on 8.5 are served at the same time.

Supervises the stack

PHP-FPM, Nginx and MariaDB run as child processes of the app, with combined logs, a stop that does not orphan workers, and an Nginx left behind by a crash reaped at the next launch.

Serves your projects on .test

Park a directory and every project inside it gets a local domain and a generated server block. Laravel, LibxaFrame, Symfony, WordPress and plain PHP are detected from composer.json first and file layout second.

Creates new applications

Name it, pick a folder, and the app resolves a suitable PHP, fetches a verified Composer if you have none, runs create-project, installs front-end dependencies with the active Node, and parks the directory.

phpMyAdmin, configured for you

One click installs it, points it at the managed database, and serves it at phpmyadminlibxa.test: bound to your machine only, because it administers the database as root.

HTTPS on your .test domains

A certificate authority created on your machine signs a certificate for any site you switch TLS on for, and one button trusts the root. No prompt for elevation, because the per-user store does not need it.

Preview a site as you configure it

The preview renders beside a site’s settings at a desktop, tablet or mobile width, so changing a version and seeing the result does not mean a window sitting on top of the controls you are using.

A terminal at the project

Open a shell already sitting in a project’s directory. Windows Terminal, PowerShell or cmd on Windows, Terminal on macOS, and the common emulators on Linux, tried in order so a missing one falls through.

It stays out of the way

Start it with your machine and leave it in the tray, where the menu carries your sites, each service with its own start and stop, and the PHP version switch. The window is there when you want it.

Integrity

Nothing runs unless it checks out.

Every runtime is fetched over HTTPS from the publisher’s own host. The SHA-256 is computed while streaming and compared before anything is extracted: a mismatch deletes the file and aborts, so an unverified binary is never put somewhere the app would later run it.

Runtime Versions Source Verification
PHP 8.0 – 8.5 downloads.php.net Publisher’s SHA-256, from the release manifest
Node.js 20 – 26 nodejs.org Publisher’s SHA-256, from SHASUMS256.txt
Nginx 1.29.4 nginx.org SHA-256 pinned in the app
MariaDB 11.4.4 archive.mariadb.org Publisher’s SHA-256, from sha256sums.txt
phpMyAdmin 5.2.3 files.phpmyadmin.net Publisher’s SHA-256, from the .sha256 file
Composer latest getcomposer.org Publisher’s SHA-256, fetched with the phar

Per-site PHP

One process per version,
not one in total.

A single php-cgi serves exactly one PHP build. Running several versions at once means one process each, and an Nginx fastcgi_pass that sends each site to the right port.

The supervisor and the config generator derive the same version-to-port map from the same site list, sorted, so a restart cannot shuffle ports out from under a config that was already written.

nginx.conf
# each site routed to the php-cgi running its version
legacy-app.test       → 127.0.0.1:9000  PHP 8.1
my-app.test           → 127.0.0.1:9002  PHP 8.4
new-app.test          → 127.0.0.1:9003  PHP 8.5
phpmyadminlibxa.test  → 127.0.0.1:9001  PHP 8.3

✓ localhost only for phpmyadminlibxa.test

Details that matter

The parts you only notice when they are wrong.

The hosts file is edited inside a marked block

Everything outside “# BEGIN Libxa Desktop” is left byte-for-byte alone, so Herd’s block and your hand-written entries survive. The write is staged to a temp file and copied by an elevated step, so the app itself never runs as administrator.

Failures name the cause and the next step

A busy port says which port and offers a free one. A privileged port says it needs elevation. Nginx exiting is reported with the line from its own error log, not “exited unexpectedly (code 1)”.

A port is checked before the process is spawned

nginx -t validates the config but never binds. The port is probed by both connect and bind, because on Windows a second socket can bind a port that is already being served, and the probe is retried for three seconds, since a database released by the previous run takes seconds to shut down.

It updates itself, but never behind your back

Checks on launch and every six hours, downloads in the background using a blockmap so only changed blocks transfer, and verifies the SHA-512. Then it waits for you to press “Restart and install”, stopping the services first.

Custom chrome and a tray menu

A frameless window with a live status pill, and a tray icon that starts, stops and opens any site without opening the window. Light by default, matching the LibxaFrame welcome page.

Security posture

A local tool with more reach than most.

The renderer is sandboxed

contextIsolation on, no Node access, a CSP with no remote or inline script. Every capability is an explicit typed method on the preload bridge.

Downloads are verified

Publisher-supplied SHA-256, checked before extraction. A mismatch deletes the file.

phpMyAdmin is localhost-only

It administers the database as root and Nginx binds every interface: on an untrusted network the default would be an open database console.

Updates are checksum-verified

The updater checks each download against the SHA-512 in latest.yml before it will install it.

Install it and park a folder.

That is the whole setup. Everything else the app fetches for you.