Examples & recipes
Copy-paste workflows for 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.yaml so it's automatic.
Create it with beamd link, or by hand:
# beamd.yaml
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. Pass the name per command:
beamd run web -- npm run dev # → https://web.<base>
beamd run api -- npm run dev:server # → https://api.<base>…or commit the ports once under services: so the names travel with the repo.
Then open needs only the service name:
# beamd.yaml
server: acme.com
scope: acme
services:
web: 5173
api: 3000beamd open web # → https://web.<base> (port 5173)
beamd open api # → https://api.<base> (port 3000)
beamd open # lists web / api to pick frombeamd link --services web=5173,api=3000 writes that block for you. The service
name becomes the label (override with --as). Point the web app at the API's
public URL with $BEAMD_URL (set by run), or hard-code the stable api.<base>.
Detached tunnels you manage
When you want tunnels to outlive the command, say 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.