A fast, rootless, open-source local PHP development environment.
Serve your projects on .test domains over HTTP and HTTPS, run a different
PHP version per site, and manage it all from one tiny daemon β no Docker, no
sudo for everyday work, no subscription.
- π Zero-config sites β drop a project in a parked folder, it's live at
<name>.test. - π Trusted HTTPS per site from a local CA β no
mkcert, no browser warnings. - π Multiple PHP versions, pinned per site.
- ποΈ Native MySQL Β· MariaDB Β· PostgreSQL Β· Redis β no Docker.
- πͺΆ One ~8 MB daemon β no containers, no VM, no Electron.
- π‘οΈ Rootless β setup elevates once; daily use never does.
- π Self-diagnosing with
yerd statusandyerd doctor.
| Laravel Herd | Lerd | Yerd | |
|---|---|---|---|
| Free | β (Pro is paid) | β | β |
| Open source | β | β | β |
| Linux support | β | β | β |
| macOS support | β | β | β |
| Windows support | β | β | β * |
Automatic .test domains |
β | β | β |
| HTTPS with a trusted local CA | β | β | β |
| Multiple PHP versions | β | β | β |
| PHP version per site | β | β | β |
| First-class CLI | β | β | β |
| Menu-bar / tray GUI | β | β | β |
| Database & cache services (MySQL Β· MariaDB Β· PostgreSQL Β· Redis) | β (Pro) | β | β |
| Runs rootless day-to-day | β | β β | β |
| No Docker / Podman / containers required | β | β | β |
| Lightweight (no VM, no container images) | β | β | β |
Built-in health checks (doctor) |
β | β | β |
| Under the hood | Native app (nginx + dnsmasq) | Containers (rootless Podman) | Native Rust (rustls proxy + embedded DNS) |
β
* = Windows is planned. Everything without an asterisk works today on macOS and Linux.
Lerd runs your stack in containers via rootless Podman (Linux +
macOS; no Docker) β so it trivially adds database/cache services, but it pulls and
runs container images rather than native processes. β Rootless by design on
Podman.
On Laravel Valet: Valet is the original macOS-only Laravel dev tool
(nginx + dnsmasq, installed via Homebrew/Composer). None of the three require it β
Herd is the native standalone successor that bundles its own nginx (and reuses
Valet's framework "drivers"), Lerd runs everything in containers, and Yerd uses
its own Rust proxy + DNS. No Valet, no Homebrew.
The easiest way to run Yerd is the desktop app β it installs the daemon and CLI for you. Grab the latest build from the releases page:
| Platform | Download | Install |
|---|---|---|
| macOS (Apple Silicon) | yerd-gui_<ver>_aarch64.dmg |
open, drag to Applications |
| Linux | yerd-gui_<ver>_amd64.AppImage |
chmod +x and run |
| Linux | yerd-gui_<ver>_amd64.deb |
sudo dpkg -i β¦ |
On first launch the app downloads and installs the yerd CLI, the yerdd
daemon, and yerd-helper into ~/.local/bin (verified against SHA256SUMS) β
so on macOS, setup is essentially drag-and-drop. It then walks you through a
one-time sudo yerd elevate to trust the local CA, route *.test, and bind
ports 80/443. Everything after runs as your user β never as root.
Prefer the terminal? Install just the daemon and CLI (no GUI):
curl -fsSL https://raw.githubusercontent.com/forjedio/yerd/main/scripts/install.sh | shThis fetches the latest release (SHA-verified) and installs yerd + yerdd +
yerd-helper β a .deb on Debian/Ubuntu, or a tarball to ~/.local/bin
elsewhere. Then run the one-time setup:
sudo yerd elevate # trust the CA Β· route *.test Β· allow 80/443# 1. Install a PHP version and make it the default
yerd install php 8.5
yerd use 8.5
# 2a. Park a directory β every sub-folder becomes <folder>.test
yerd park ~/Sites
# ~/Sites/blog -> http://blog.test
# 2b. β¦or link a single project under a name you choose
yerd link my-app ~/code/my-app
# -> http://my-app.test
# 3. Turn on HTTPS for a site
yerd secure my-app
# -> https://my-app.test (trusted, thanks to the local CA)
# 4. Pin one site to a different PHP version
yerd use my-app 8.3
# 5. See what's going on / fix problems
yerd status
yerd doctor
yerd doctor fixOpen https://my-app.test in your browser β that's it.
| Command | What it does |
|---|---|
yerd park <dir> |
Park a directory; each child folder is served at <name>.test. |
yerd unpark <dir> |
Stop serving a previously parked directory. |
yerd link <name> <dir> |
Serve a single directory as a named site. |
yerd unlink <name> |
Remove a linked site. |
yerd sites |
List every known site (kind, PHP version, HTTPS, doc-root). |
yerd root <site> [path] |
Set a site's served web root (or --auto to re-detect). |
yerd use <version> |
Set the global default PHP version. |
yerd use <site> <version> |
Set one site's PHP version. |
yerd secure <site> / unsecure <site> |
Turn HTTPS on / off for a site. |
yerd install php <version> |
Download + install a PHP version. |
yerd list php [--check] [--available] |
List installed PHP versions (and updates), or what's installable. |
yerd update php [<version>] |
Update one (or all) installed PHP versions. |
yerd set php <setting> <value> / unset php <setting> |
Set / clear a global PHP ini default (all versions). |
yerd restart php [<version>] / restart daemon |
Restart a PHP pool (or all), or the daemon. |
yerd services |
List local database / cache services and their status. |
yerd service available |
List installable service versions for your platform. |
yerd service install <svc> <version> |
Install a service (redis/mysql/mariadb/postgres) from a prebuilt build. |
yerd service start|stop|restart <svc> |
Start, stop, or restart a service (start also enables auto-start). |
yerd service set-port <svc> <port> / logs <svc> |
Set a service's loopback port; tail its log. |
yerd service change-version|uninstall <svc> β¦ |
Switch a service's version, or remove one (--purge deletes its data). |
yerd db list|create|drop <svc> [<name>] |
List, create, or drop databases in a running SQL service. |
yerd db backup|restore <svc> <name> <file> |
Dump a database to / restore it from a plain-SQL file. |
yerd status |
Snapshot: daemon, ports, DNS, CA trust, PHP pools (PID/RAM), load. |
yerd doctor / yerd doctor fix |
Diagnose common problems; auto-repair the safe ones. |
yerd elevate [trust|resolver|ports] |
One-time privileged setup (run with sudo). |
yerd unelevate [...] |
Reverse what elevate configured. |
Add --json to any command for machine-readable output.
Yerd is built around a few deliberate decisions that make it safe, fast, and maintainable.
Yerd runs as three pieces, and the GUI/daemon never run as root:
yerddβ the unprivileged per-user daemon. It owns all runtime state and serves the proxy, DNS, and PHP-FPM pools.yerdβ the CLI, a thin client that just talks to the daemon over a per-user socket.yerd-helperβ a strict, auditable one-shot binary for the handful of operations that genuinely need root (trust the CA, configure the DNS resolver, grant the port capability). It takes typed arguments, never shells out, never touches the network, does exactly one thing, and exits.
Setup may elevate once; daily use never does.
Yerd generates a local certificate authority and issues a leaf certificate per
site on demand, terminated by a hand-rolled rustls reverse proxy.
sudo yerd elevate trust adds the CA to your system trust store β after that,
every .test site is green-padlock valid. No OpenSSL anywhere.
The daemon owns state. The CLI and the GUI are both clients β they never reimplement daemon logic, so the CLI and GUI can never disagree.
Pure logic lives in library crates. I/O and OS calls are pushed to the edges behind traits.
Business logic is unit-tested with in-memory fakes; real filesystem, network,
process, and OS calls live behind traits (ProcessSpawner, TrustStore,
ResolverInstaller, PortBinder, Clock, β¦) with one implementation per OS.
The result: a large, fast test suite and behaviour that's identical across
platforms.
Yerd makes no network calls except the ones you explicitly ask for (downloading the PHP builds you install). PHP updates are notify-only β Yerd tells you when a newer patch exists, but never installs anything behind your back.
Yerd v2 is a ground-up rewrite of our own v1 package
(LumoSolutions/yerd) β the Go tool we
first built to scratch this itch. Shipping v1 taught us a lot, and we rebuilt Yerd
from scratch in Rust to make it cross-platform, rootless, and far easier to
maintain. v1 is reference-only: there's no command-surface or config-format
compatibility. Where v1 built PHP from source and leaned on sudo for most
operations, v2 ships prebuilt PHP and runs unprivileged.
Licensed under the MIT License.
A Forjed project Β· github.com/forjedio/yerd