Start
Each command runs in its own process session, with the port it was given in PORT and a small, deliberate environment.
v1.3.2 · macOS & Linux
grat starts the long-running commands a project needs, waits until each one is genuinely ready, keeps their ports out of each other's way, and can put a single path on the public internet when a webhook has to reach you.
MIT licensed. One binary, no daemon, no config server.
Starting services example.com [info] backend checking managed state [...] backend starting isolated process [...] backend waiting for listener and health probe [ok] backend ready on http://127.0.0.1:4001/ [info] frontend checking managed state [...] frontend starting isolated process [ok] frontend ready on http://127.0.0.1:3000/ [ok] worker ready Status example.com SERVICE STATE PORT PID ENDPOINT PUBLIC frontend running 3000 16445 http://127.0.0.1:3000/ backend running 4001 16435 http://127.0.0.1:4001/ worker running - 16462
Release binaries are published for macOS and Linux on Intel and ARM, verified against their checksums and GitHub's signed attestation.
grat.config from the scripts your project already has.A process that has been launched is not a service that answers. grat waits for a listener owned by the command it started, then for the health path to return, and only then calls it ready.
Each command runs in its own process session, with the port it was given in PORT and a small, deliberate environment.
Signals reach the process group grat created, and only after the live PID, start identity and group all match what it recorded.
Output goes straight to .grat/log/, so a service keeps its log after the command that started it has exited.
Ports stop being a thing you remember. A service's role decides the range it may live in, and grat allocates inside it, across every project it knows about.
A payment provider confirms from server to server, to an address it reaches from the internet. grat makes one of your services reachable there, at a name that stays the same, and sets Tailscale up on the way if it is missing.
Running the command is the decision, so nothing has to be prepared first. Where only a callback has business with the internet, name the path and everything else stays inside.
Exposing service example.com [info] Tailscale is not installed on this machine [info] Command brew install tailscale [...] Tailscale installing [ok] Tailscale installed [info] Tailnet this machine is signed in to no tailnet [...] Sign-in opening the page in your browser [ok] Tailnet this machine is connected [...] backend publishing /api/webhooks/creem [ok] backend reachable at https://mini.tail1234.ts.net/api/webhooks/creem