Introduction
Every worktree of every repo becomes a context with its own hostname, ports, and env vars, so every branch you or an agent is on can run at once.
You probably have a feature you’re working on, a PR you promised to review, and an agent or two grinding away on branches of their own, sometimes in a different repo. Nothing stops you running all of that at once. Nothing coordinates it either. You pick ports by hand, you edit .env in each checkout, and you swear you’ll put it all back afterwards. So mostly you stop one thing to look at another.
Grove uses worktrees to keep contexts separate. Every worktree of every repo on your machine is a context, and each one gets its own hostname, its own ports, and its own env vars. One daemon serves them all, so run as many worktrees on as many projects as you like and they won’t collide:
~/code/app https://app.grov.site web:20107 db:20402
~/worktrees/app/feat https://app-feat.grov.site web:20871 db:20533
~/code/shop https://shop.grov.site web:20334 db:20118
No port in the URL, a certificate your browser actually trusts, and one command to run anything inside that context:
grove exec -- vite dev
There’s nothing to configure per worktree. Ports come from a hash of the worktree and the thing being served, so a fresh checkout is addressable the moment it exists and leaves nothing behind when you delete it. And since the worktree’s name is a value you can template, {context.slug} in a database URL points each one at its own database on the postgres you’re already running.
Where to start
Quickstart
Four commands from nothing to a hostname that opens.
Why not lando or ddev?
What grove keeps from them, what it drops, and what it asks of your project.
Setting up a machine
The certificate authority, the trust stores, and the one privileged step.
Setting up a project
What grove init writes, and how to read grove.toml.
How it works
A context is a worktree, named from its directory. The daemon terminates TLS for *.grov.site, which is real wildcard DNS pointing at loopback, and proxies each context’s hostname to a port it leased for that context. Ports are derived from a hash rather than stored, and a lease lasts exactly as long as the command holding it, so there’s no state to clean up when a worktree goes away. The Concepts section says how each of those decisions is made and why.