Examples & recipes
Copy-paste workflows — per-branch previews, multi-app dev, CI, and driving Beamd from a script.
Practical patterns built from the CLI reference. All of these work the same on the hosted service and a self-hosted edge.
Per-branch preview URLs
Give every branch its own stable URL. Commit a .beamd so it's automatic:
# .beamd
server: acme.com
scope: acme
from: branchbeamd run -- npm run dev
# main → https://main.<base>
# feat/login → https://feat-login.<base>The branch name is slugified to a single label (slashes → hyphens). See Naming.
Multi-app dev (web + api)
Run a frontend and backend side by side, each at its own name. Two terminals:
beamd run web -- npm run dev # → https://web.<base>
beamd run api -- npm run dev:server # → https://api.<base>Point the web app at the API's public URL with $BEAMD_URL (set by run), or
hard-code https://api.<base> since the name is stable.
Detached tunnels you manage
When you want tunnels to outlive the command — e.g. for an agent or a long review session — detach them and manage by name:
beamd open 3000 --as api -d # returns immediately; agent holds it
beamd open 5173 --as web -d
beamd list # see what's up
beamd close web # tear one downDriving Beamd from a script
Use --json and read the url field — never assemble the host yourself:
URL=$(beamd open 3000 --as api -d --json | jq -r .url)
echo "Preview: $URL"
# ... do work ...
beamd close api --jsonopen -d spawns the background agent on first use; close never spawns one and
exits 0 whether or not the tunnel existed. For a typed contract instead of
shelling out, see the Agent local API.
Using Beamd in CI
CI is headless, so authenticate with a workspace API key in a dedicated config file rather than an interactive login:
# beamd.ci.yaml holds { server, token: <workspace API key> }
beamd open 3000 --as pr-$PR_NUMBER -d --json --config beamd.ci.yamlClose it (or let the cap recycle it) when the job ends. Why an API key and not a login: Auth & tokens. Bundling the binary into a job or app: Embed in your app.