Search docs

Search the Beamd documentation

How it works

One binary, an edge, and a background agent — how a local port becomes a public HTTPS URL, and what happens when the network blips.

Beamd is a single binary that plays two roles. On a server it's the edge (beamd serve); on your machine it's the client (beamd open). The client holds one outbound connection to the edge, and the edge fans public HTTPS traffic back down it to your local app.

One binary, two roles

  • Edge — runs on a box with a public IP, owns a domain (e.g. beam.example.com), terminates TLS, and routes each <name>.<base> host to the right developer's connection. You run one. See Self-hosting.
  • Client — runs on your laptop. beamd open 3000 dials the edge, registers a name, and forwards requests to localhost:3000.

The hosted service runs the edge for you; self-hosting means you run it. The developer commands are identical either way.

The path of a request

[ Internet ]
     │
     ▼  :443 (TLS, real Let's Encrypt cert)
[ beamd edge ]  ── ACME DNS-01 ──▶  [ your DNS provider ]
     ▲
     │  one outbound TLS connection per developer
     │  (ALPN "beam/1", yamux-multiplexed — many tunnels share it)
     ▼
[ beamd client ]
     │  loopback
     ▼
[ your local apps :3000, :3001, ... ]

The client dials out to the edge, so there's nothing to expose or port-forward on your side. A single multiplexed connection carries every tunnel you open, and the edge maps the request's Host header to the matching local port.

Foreground vs detached (the agent)

A bare beamd open runs in the foreground and holds the tunnel until you Ctrl-C — exactly like ngrok.

Add -d / --detach and the tunnel is handed to a background agent that keeps it alive after the command returns. The agent owns the connection and exposes a small local API; beamd list, beamd status, and beamd close manage what it's holding. One agent runs per account. The agent and its API are covered in Agent local API.

Names and routing

Every tunnel gets a single-label subdomain — api.beam.example.com. The label defaults to the port and can be set with --as or derived from your project with --from. The full rules (and the one-label constraint) are in Naming & project config.

Certificates and DNS

The edge issues wildcard certificates from Let's Encrypt over the DNS-01 challenge, so a brand-new <name>.<base> is already covered — no per-tunnel issuance latency. That's why the edge needs DNS API credentials; see DNS providers.

Resilience

Tunnels survive network blips. If the connection drops, the client reconnects and replays your registrations automatically — detached tunnels come back without you touching anything. The agent is not a persistent registry across reboots, though: after a restart, re-open what you want exposed (it's cheap and idempotent).