A native local development environment in Rust.
Grove serves *.test domains with automatic routing, local HTTPS, multi-version
PHP and zero external dependencies — from a single Rust core.
Local PHP/Laravel development today means choosing between friction points:
- Laravel Valet is elegant and light, but macOS-only and leans on Homebrew + Composer + dnsmasq.
- Herd ships static binaries but is closed, won't let you load custom PHP extensions, and gates databases, mail testing and dumps behind a Pro license.
- Docker / Sail is flexible but heavy and slow for simple local work.
Grove takes a different path: one Rust codebase, three platforms, and nothing to install around it.
| Valet | Herd | Docker/Sail | Grove | |
|---|---|---|---|---|
| Cross-platform | macOS only | macOS + Win | ✅ | ✅ |
| No Homebrew/Composer/dnsmasq | ❌ | ✅ | ➖ | ✅ |
| Custom / bring-your-own PHP | ✅ | ❌ | ✅ | ✅ |
| Bundled static PHP | ❌ | ✅ | ➖ | ✅ |
| Idle footprint | tiny | small | heavy | tiny |
| Open / no license wall | ✅ | ❌ | ✅ | ✅ |
- 🌐 Automatic
*.testrouting via an embedded DNS resolver — no manual hosts editing. - 🔒 Local HTTPS with a private root CA and on-demand per-site leaf certificates.
- 🐘 Bundled PHP — install multiple self-contained versions (
grove php install 8.5|8.4|8.3), with per-siteisolateand lazy FPM pools. - 🐞 Step-debugging —
grove debug onloads Xdebug into the FPM pools (trigger mode, zero idle overhead) so a DAP-capable editor can set breakpoints;grove debug envwires up CLI debugging (artisan, tests). - ⬢ Bundled Node.js — download node · npm · npx, with per-site Node versions; no nvm or Homebrew.
- 🗄️ Bundled services — Grove downloads and supervises PostgreSQL, MySQL and Redis itself, so there is no database/cache or Homebrew to install separately.
- 📧 Built-in mail-catcher — an SMTP server that captures outgoing mail, with a Mailpit-style viewer.
- 🌍 Public tunnels —
grove shareexposes a local site to the internet (demos, webhooks) via a self-hostable, native Expose/ngrok alternative. - 📦 Reproducible environments — commit a
grove.toml(PHP/Node versions, services, HTTPS, dev), and a teammate goes fromgit cloneto a running, identical setup with onegrove up. - ⇄ Request timeline — Grove is the proxy, so it records a live, framework-agnostic log of every request (method, path, status, duration) — a zero-config Telescope for any site, in the CLI (
grove requests) and a live GUI panel. - 🛠 Tools — migrate MySQL from Herd, and convert whole databases between MySQL, PostgreSQL and SQLite.
- ⏱️ Database snapshots —
grove db snapshottakes a point-in-time SQL snapshot of the bundled MySQL/PostgreSQL andgrove db restorerolls it back, so risky migrations are fearless. - 🔀 Toolchain on your PATH —
grove path installputs the bundledphp,composer,node,npmandlaravelon your PATH, auto-switching to each project's pinned version — so you can drop Herd/Valet entirely. - 🐳 Docker / OrbStack aware — auto-discovers containers and serves them as
<name>.testwith trusted local HTTPS, next to native sites. - ⚡ Runs your dev processes —
grove devsupervisesnpm run dev(Vite HMR) + a queue worker per site; noartisan serveneeded. - 🧩 Driver system — Laravel, WordPress, generic PHP, static sites, and reverse proxy (Vite/Node).
- 🌱 Create / import sites — scaffold a new Laravel or static project, or link existing ones.
- 🖥️ GUI + CLI in parity — both are thin clients over the same daemon, plus a macOS menu-bar icon.
- 🔌 Zero external dependencies — DNS, proxy, FastCGI and TLS are all built in.
Grove has no runtime dependency on Homebrew, Composer, dnsmasq, OpenSSL or
Laravel Valet. DNS, the reverse proxy, FastCGI and TLS are all built into the
Rust core. Even PHP can be downloaded as a self-contained static binary via
grove php install — it links only against the operating system's own
libraries. grove import reads an existing Valet config if one is present,
but it never requires Valet to be installed.
📘 New here? Read the full installation guide — a step-by-step manual with example terminal output, a first site, HTTPS, services and troubleshooting.
# 1. First-run setup: config, root CA, a static PHP build, resolver + trust
sudo grove init
# 2. Install the background service (root daemon, binds 80/443/53, starts at boot)
sudo grove install
# 3. Point Grove at your projects
grove park ~/Code # every subdirectory becomes <name>.test
# or, inside one project:
grove link
# 4. Open https://myproject.test 🎉
grove secure myproject # enable HTTPS
grove isolate myproject 8.3 # pin a PHP version for this siteThe daemon binds privileged ports (53/80/443) and runs PHP as your user, so it is installed as a root service.
sudo grove startworks too for a foreground/one-off run.
From a clean machine to a running *.test Laravel app in under five minutes —
no Homebrew, no Composer, no Valet.
| Category | Commands |
|---|---|
| Setup | init, ca trust / ca uninstall, install / uninstall (service) |
| Lifecycle | daemon, start, stop, restart |
| Sites | new, up (from grove.toml), park / unpark, link / unlink, list, secure / unsecure, isolate / unisolate, proxy |
| PHP | php install, php register, php discover, php list, use |
| Node | node list, node install <version>, node use <site> <version>, node unuse <site> |
| Services | service list, service install, service start, service stop, service restart |
| Databases | db snapshot, db list, db restore <id>, db rm <id> |
| Observability | requests [site] (live request timeline) |
| Toolchain | path install, path show, path uninstall |
| Dev | dev start <site>, dev stop <site>, dev list |
| Tunnels | share <site> (public URL via grove-tunnel server) |
mail, mail show <id>, mail clear |
|
| Logs | logs (list sources), logs <site> (view entries) |
| Operations | status, doctor, env [site], import (Valet) |
Every command supports --json for scripting and Elyra Conductor integration.
The GUI is a thin client that proxies everything to the daemon over the same
grove-ipc JSON-RPC the CLI uses — they are always in parity. The frontend is
Svelte 5 + Vite and shares the Elyra Conductor look & feel (Tokyo Night palette,
JetBrains Mono). The dashboard surfaces every site with its driver, PHP version,
a one-click HTTPS toggle, isolate, and shortcuts to open in the browser or
Finder, alongside service, mail, tunnels, tools, logs and doctor panels. The
Requests panel is a live, framework-agnostic timeline of every request Grove
proxies (status colour-coding, slow-request highlighting, per-site filter). The
Logs panel parses per-site Laravel logs and Grove's own service logs into a
level/date/message view with a stacktrace detail pane. A Settings panel (⌘,)
manages parked paths, the TLD, default PHP, the mail-catcher port,
launch-at-login and the theme (auto/light/dark).
# Build the frontend (the GUI binary embeds it at compile time)
cd crates/grove-gui/ui && pnpm install && pnpm build && cd -
# Build and launch
cargo build --release -p grove-cli -p grove-gui
grove gui # starts the daemon if needed, then opens the appAfter changing the UI, rebuild the frontend and grove-gui so the new bundle
is re-embedded. Closing the window keeps Grove running in the menu bar; quit via
the menu-bar icon.
Grove's source of truth is a single declarative TOML file
($GROVE_HOME/config.toml). Runtime state that can be re-derived is kept out of
it, so the file stays human-readable and diff-friendly.
[general]
tld = "test"
default_php = "8.4"
auto_start = true
[[parked]]
path = "~/Code"
[services]
mail_enabled = true
mail_port = 1025
[[sites]]
name = "inside-next"
path = "~/Code/inside-next"
php = "8.4" # per-site PHP
node = "22" # per-site Node
secure = true
driver = "laravel"
[[sites]]
name = "frontend"
path = "~/Code/frontend"
driver = "proxy"
proxy_to = "http://127.0.0.1:5173"A single long-running daemon binds the privileged ports (DNS 53, HTTP 80, HTTPS 443) and supervises the FPM pools. The CLI and GUI are thin clients that talk to the daemon over local IPC.
grove-core site registry, driver detection, config, paths (pure, no OS I/O)
grove-ipc JSON-RPC protocol + transport (CLI/GUI ↔ daemon)
grove-tls root CA + leaf issuance (rcgen/rustls)
grove-dns embedded resolver for *.<tld> (hickory)
grove-proxy HTTP/HTTPS proxy + minimal FastCGI client (hyper)
grove-runtime PHP version + FPM pool supervisor
grove-os platform integration (resolver, trust store, elevation)
grove-daemon long-running process: binds ports, serves IPC
grove-cli clap frontend (binary: `grove`)
grove-gui Tauri 2 + Svelte 5 desktop GUI (thin client over grove-ipc)
# Requirements: Rust 1.80+, and (for the GUI) Node 20+ with pnpm.
cargo build --release # build the CLI + daemon
cargo test # run the test suiteFor local testing without binding privileged ports, set an isolated home and high ports:
export GROVE_HOME=/tmp/grove-home
mkdir -p "$GROVE_HOME"
cat > "$GROVE_HOME/config.toml" <<'EOF'
[general]
tld = "test"
default_php = "8.4"
http_port = 8080
https_port = 8443
dns_port = 5354
[[parked]]
path = "~/Code"
EOF
grove daemonFrom 0.1.2 the macOS app is code-signed with a Developer ID and notarized
by Apple, so it opens normally — download the .dmg, drag Grove to
/Applications, and launch it. No Gatekeeper warning, no workarounds.
To actually serve *.test (which needs ports 53/80/443), install the background
service once: sudo grove install. The GUI is a dashboard over that daemon.
Everything above is free and open source, forever — the core is never gated. Grove Pro ($99/seat/year) unlocks power features on top:
- Database client — a built-in Database panel that auto-connects from each
site's
.env. Browsing +SELECTis free; Pro adds inline row editing, a schema inspector, and a production-safety guard. - End-to-end encrypted team secret sync (
grove secret) — a project's.envshared securely, never pasted into a chat window. Encrypted on your machine (age/X25519); the backend only ever stores ciphertext.
Licenses are verified offline. See Pro & Teams.
- Installation guide · Pro & Teams · Docker · Tunnels · Debugging · Architecture · Configuration · Commands · Testing
- Changelog
Contributions are welcome! See CONTRIBUTING.md to get started, and please follow our Code of Conduct. For security issues, see SECURITY.md.

