Introducing Libxa Desktop
A local development environment that installs and supervises PHP, Node, Nginx and MySQL, serves every parked project on a .test domain, and scaffolds new applications: starting from a machine with nothing on it.
Libxa Desktop is a local development environment for Laravel, LibxaFrame and
plain PHP. It installs and supervises PHP, Node, Nginx and MySQL, serves every
project on its own .test domain, and scaffolds new applications: starting
from a machine with nothing on it.
The premise
Most local-environment tools assume you already have a stack. This one assumes you have nothing, and does not ask you to fix that first.
Open it on a clean Windows machine and the Services tab offers to install
Nginx and MariaDB. The PHP tab offers 8.0 through 8.5. The Node tab offers 20
through 26. Everything lands in the app's own data directory. Nothing is added
to your PATH, and no system directory is touched.
Nothing runs unless it checks out
Every runtime is fetched over HTTPS from the publisher's own host, and the SHA-256 is computed while streaming and compared before anything is extracted:
| Runtime | Source | Checksum from |
|---|---|---|
| PHP 8.0 – 8.5 | downloads.php.net |
the official release manifest |
| Node 20 – 26 | nodejs.org |
that release's SHASUMS256.txt |
| Nginx | nginx.org |
pinned in the app: they publish no per-file hash |
| MariaDB | archive.mariadb.org |
their sha256sums.txt |
| Composer | getcomposer.org |
the hash published beside the phar |
A mismatch deletes the file and aborts. An unverified binary is never put somewhere the app would later run it.
Nginx is the exception worth explaining: nginx.org signs releases with PGP but publishes no per-file checksum, so the hash is recorded from the official file over TLS and pinned in the app. A changed upstream file fails loudly rather than being installed unverified.
Park a folder
Point the app at the directory your projects live in. Every subfolder with a
real front controller becomes a site at folder-name.test, with an nginx
server block generated for it.
Laravel serves public/, LibxaFrame serves src/public/, WordPress serves the
root. Detection reads composer.json first and file layout second, so a
project is identified before it is served rather than guessed at afterwards.
A composer.json alone is not enough: a library has one too. Directories that
are skipped are logged with the reason, because "why is my project missing
from the list" is otherwise unanswerable.
Domains that actually resolve
A local domain does nothing until it maps to 127.0.0.1. The app writes them
into the hosts file inside a marked block:
# BEGIN Libxa Desktop - managed automatically, do not edit
127.0.0.1 my-app.test
# END Libxa Desktop
Everything outside those markers is left byte-for-byte alone: Herd's own block survives, and so do your hand-written entries. The file is system-owned, so the write is staged to a temp file and copied by an elevated step. The app itself never runs as administrator.
Create a new application
Sites → New site asks for a name and a directory. The app resolves a PHP
that meets the starter kit's minimum, fetches a verified Composer if your
machine has none, runs create-project, installs front-end dependencies with
your active Node, and parks the directory so the result is served immediately.
Composer's output streams into the dialog rather than hiding behind a spinner. A dependency install takes minutes, and a progress bar with no detail leaves you unable to tell a slow download from a stuck one.
Failures that say what to do
A local stack fails in a small number of predictable ways, and the difference between a good tool and a frustrating one is what it says when that happens.
- A busy port names the port and offers one that is free.
- A port under 1024 says it needs administrator privileges, rather than reporting it as a clash.
- Nginx exiting is reported with the line from its own error log: nginx reopens that log before it binds, so a bind failure never reaches stderr and the exit code alone tells you nothing.
- An nginx left running by a crash is stopped at the next launch, using its own pid file, so it cannot take a system or Herd nginx with it.
Getting it
Windows 10 or 11, 64-bit. The app updates itself afterwards: it checks on launch and every six hours, downloads in the background using a blockmap so only the changed parts transfer, verifies the SHA-512, and then waits for you to press Restart and install.
Builds are not code-signed yet, so Windows shows "Windows protected your PC" the first time. That is a missing certificate, not a sign the download is unsafe, but it does mean you should only install builds from the releases page.