pond CLI reference
Every pond subcommand, what it does, when to reach for it, and the flags that matter.
For the full list of any command's flags, run pond <command> --help. This page focuses on intent and common use.
At a glance
| Command | What it does |
|---|---|
pond new |
Scaffold a new capsule from a template or a free-form description |
pond dev |
Start the local dev server with hot reload |
pond deploy |
Ship the capsule — hosted on pond.run by default, --local for offline |
pond start |
Run a previously-built local deploy bundle |
pond inspect |
Peek at a running capsule's state (schema, sockets, ai, blob, env) |
pond logs |
Stream a capsule's logs |
pond db |
Inspect, dump, back up, and restore the capsule's SQLite |
pond fork |
Clone a public capsule's source from a deploy URL |
pond claim |
Take ownership of an anonymous hosted deploy |
pond signup |
Friendly first-account flow — create a user + claim the current deploy |
pond host |
Run your own hosted control plane (the thing pond deploy deploys to) |
pond login |
Save a user API token for a control plane |
pond dashboard |
Open the per-host project dashboard in your browser |
pond user |
Create / list / promote users on a control plane (admin) |
pond token |
Rotate the saved user token |
pond domains |
Attach a custom subdomain to a hosted deploy |
pond env |
Set, unset, or list env vars on a hosted deploy |
pond auth |
Manage your local dev-server guest identity |
pond new
Scaffold a new capsule directory. Accepts either a single slug (treated as a name) or a free-form description (treated as a prompt and slugified into a directory name).
When to use: starting a brand-new app. Combine with --generate if you want a locally-detected agent (hermes → claude → codex) to fill in the code from your prompt.
Key flags:
--template <name>— start from a named template instead of the heuristic pick. Runpond new --list-templatesto see them all.--generate— after scaffolding, invoke the first detected local agent to implement the prompt. With this flag a blank-canvas stub is written and the agent drives the design end-to-end.--dir <name>(alias--name_flag) — override the auto-derived directory name when passing a prompt.--no-git— skipgit initin the new directory.
# Just a name → starts from the auto-picked template
pond new my-app
# A description → slugified to a dir, AGENTS.md captures the prompt
pond new "a kanban board with markdown cards"
# Same prompt, but an agent writes the code right after scaffolding
pond new "a habit tracker with streak counts" --generate
# Pick a specific template regardless of the prompt
pond new analytics-dash --template todo
pond dev
Start the development server. Watches server/index.ts, client/index.tsx, shared/, and .env.pond.server, rebuilding on change. Serves the rendered HTML, the bundled JS, and the capsule's queries/mutations/sockets.
When to use: every time you're iterating on a capsule locally.
Key flags:
--port <n>— preferred port (default3000). If it's busy the server walks forward up to 20 ports and tells you which one it landed on (added 0.2.5).
pond dev
# → pond dev server running at http://localhost:3000
pond deploy
Build and ship the capsule. Hosted by default — bare pond deploy uploads to https://pond.run, prints the live URL, the IDE URL, and a one-time claimToken (saved to .pond/deploy.json).
The CLI picks the deploy target in this order:
--local→ offline bundle (no upload). Run withpond start.--api <url>→ use that control plane..pond/deploy.jsonalready records anapiUrlfrom a previous deploy → redeploy to the same host. This is howpond deploy"remembers" which control plane this capsule lives on after the first deploy.- Otherwise →
https://pond.run(anonymous). A→ No deploy target set; uploading to https://pond.run …notice prints before the upload so the behavior isn't invisible.
Key flags:
--local— build a standalone bundle in.pond/deploy-bundle.mjsinstead of uploading. Use for airgapped / self-host shipping.--api <url>— explicit control plane URL (e.g.https://my-host.example.com).--token <value>— user API token. Overrides~/.pond/credentials.jsonfrompond login.--push-env— also upload.env.pond.serverto the control plane (otherwise env stays local).--public-inspect— allow/__pond/inspectrequests without a claim token (default: claim-token required).--port <n>— port baked into the local bundle (default3000, only meaningful with--local).
# Anonymous hosted deploy on pond.run — returns a live URL + claimToken
pond deploy
# Authenticated hosted deploy, env pushed
pond deploy --push-env
# Self-hosted control plane
pond deploy --api https://my-host.example.com
# Offline bundle for `pond start` / shipping yourself
pond deploy --local
After a hosted deploy, the URL + claimToken are saved to .pond/deploy.json (mode 0o600). The token is one-time — claim or rotate immediately.
pond start
Run a local deploy bundle previously produced by pond deploy --local.
When to use: smoke-testing a production build on your machine, or serving the bundle behind your own reverse proxy.
Key flags:
--port <n>— port to bind (defaults to theportsaved in.pond/deploy.json; falls back to3000).
pond deploy --local # produces .pond/deploy-bundle.mjs
pond start # serves it
PORT=8080 pond start # env-var override
pond inspect
Snapshot a running capsule: declared tables, registered sockets, AI providers, blob storage, env-var presence, runtime version.
When to use: confirming a deploy actually has the schema and config you expect, or debugging "is the env var set?" without rolling logs.
Target resolution (since 0.3.10):
--local→ forcelocalhost:<port>.- Explicit
targetpositional (URL ordeployId) → use it. .pond/deploy.jsonexists withurl+claimToken→ auto-target the hosted deploy, prints→ Inspecting <url> (pass --local for the dev server)to stderr.- Otherwise → fall back to
localhost:<port>.
Key flags:
--port <n>— localhost port (default3000).--local— force localhost even if.pond/deploy.jsonpoints at a remote.<target>(positional) —deployId, full URL, or omit to auto-target.
pond inspect # auto: remote if deployed, else local
pond inspect --local # force local dev server
pond inspect https://abc.pond.run # explicit remote
pond logs
Stream stdout/stderr from a running capsule via Server-Sent Events.
When to use: watching live activity, or tailing a hosted deploy you just shipped.
Target resolution: identical to pond inspect — --local forces localhost, an explicit --target wins, otherwise auto-target the deploy in .pond/deploy.json, falling back to localhost:<port>.
pond logs # auto-target the hosted deploy
pond logs --local # force local dev server
pond logs --target https://abc.pond.run # explicit remote
A friendly hint fires if the chosen target refuses (ECONNREFUSED) — no more raw undici stack traces when the dev server isn't running.
pond db
Inspect, dump, back up, and restore the capsule's SQLite database. Same target-resolution rules as pond inspect apply to every subcommand: --local to force localhost, explicit --target, or auto-target from .pond/deploy.json. Bare pond db now prints help cleanly (exit 0) instead of erroring with No command specified.
pond db list
List table names declared in the schema.
pond db list
pond db dump [table]
Dump rows. With no argument, dumps every table. With an argument, dumps that one.
pond db dump # entire database
pond db dump habits # one table
pond db backup --out
Snapshot the SQLite file to a local path (uses VACUUM INTO — safe to run on a live database).
pond db backup --out ./snap.sqlite
pond db restore --in
Upload a SQLite snapshot. The capsule writes it to .pond/data.db.restored — restart the process to swap it in.
pond db restore --in ./snap.sqlite
pond fork
Clone a public capsule from a deploy URL. Pulls the source tree from /api/deploys/<id>/source, writes it to a new local directory, scaffolds package.json / node_modules, and you're ready for pond dev.
When to use: starting from someone else's capsule, or recovering source from a deploy you lost the local copy of.
Key flags:
<deploy>(positional, required) — deploy URL likehttps://abc.pond.run, or a rawdeployId.--name <name>— override the local directory name (default: derived from the capsule title or deployId).--api <url>— control-plane base URL. When omitted, the API base is derived from the deploy URL — but onlypond.run/*.pond.runhosts are trusted by default. Pass--apiexplicitly to fork from any other control plane.--no-git— skipgit init.--allow-scripts— permit forking apackage.jsonthat defines npm lifecycle scripts (preinstall/install/postinstall/prepare/postprepare). Off by default: those scripts run automatically onnpm installand are an RCE vector if the upstream is hostile. The CLI refuses the fork and names the offending scripts unless this flag is passed. Since 0.3.11, the control plane also refuses to accept uploads that contain these scripts (POST/PUT/api/deploys, single-file PUT/files/package.json) —--allow-scriptsonly matters when forking from an older control plane or a self-hosted one that pre-dates the upload-side check.
pond fork https://abc.pond.run
pond fork https://abc.pond.run --name my-copy
pond claim
Take ownership of an anonymous hosted deploy by presenting its claimToken, or reattach an already-owned deploy from a new machine. For the friendliest first-time path, use pond signup — it wraps this command.
Authorization rules:
- Anonymous deploy (just created via
pond deploy, not yet claimed): a validclaimTokenis sufficient. Pair with--signup <name>to mint a new user in the same call, or withAuthorization: Bearer <token>(an existing user account) to claim under that account. - Already-claimed deploy (since 0.3.9): the
claimTokenalone is not sufficient to transfer ownership. The caller's bearer token must belong to the current owner or be an admin. Attempts by a different user are rejected with403 "Deploy already owned by another account"and audited asdeploy.claim_denied. This closes the takeover path where a leakedclaimTokencould dispossess the original owner.
When to use: cross-machine ownership reattachment (the legitimate owner re-targeting from a new laptop), or explicit control over the claim step. For day-one "I just deployed and want an account," prefer pond signup.
Key flags:
- Reads
.pond/deploy.jsonfrom the cwd fordeployId,apiUrl, andclaimToken. --signup <name>— create a new user with this username and claim in one shot (anonymous deploys only).--api <url>— override the API URL from.pond/deploy.json.
pond deploy
# → deployId: abc123…, claimToken: tk_… (one-time disclosure; server stores only the hash)
pond claim # uses .pond/deploy.json (existing user, must be current owner)
pond claim --signup your-username # claim + create user (anonymous deploys only)
Since 0.3.10, the control plane stores only sha256(claimToken) on disk — a backup leak no longer yields usable tokens. The plaintext lives only in your local .pond/deploy.json (mode 0o600) and is returned once at create time.
pond signup
Create an account on a pond control plane and claim the current anonymous deploy under it — in one command. Wraps pond claim --signup with a name that matches the user's mental model.
When to use: day-one. You ran pond new and pond deploy and now you want an account that owns this deploy. This is the one-line shortcut.
Key flags:
<username>(positional, required) — the username to create (matches/^[a-z0-9_-]{1,32}$/i).--api <url>— override the apiUrl from.pond/deploy.json(rarely needed — the deploy already knows where it lives).
# Three-command first-run flow
pond new my-app
pond deploy # anonymous deploy on pond.run, gets a URL + claimToken
pond signup torrey # account "torrey" created, this deploy claimed under it
If there's no .pond/deploy.json (you haven't deployed yet), pond signup refuses and points at pond deploy. Signup without an attached deploy is intentionally not supported — it would create a dangling account.
pond host
Run your own pond control plane — the server that accepts pond deploy, builds bundles, hosts user workers, and serves anonymous deploys.
When to use: self-hosting pond instead of (or alongside) pond.run. Production: put it behind a TLS-terminating proxy and set --public-base-url.
Key flags:
--port <n>— bind port (default8787).--host <iface>— interface to bind, default127.0.0.1. Use0.0.0.0to accept external traffic (only if you also have a TLS proxy).--public-host <name>— hostname used in returned deploy URLs (defaultlocalhost). Use this if your proxy hostname differs from--host.--public-base-url <url>— full external URL incl. scheme, e.g.https://pond.example.com. When set, deploy URLs use this base instead ofhttp://<public-host>:<port>. Required when you're behind TLS.--data-dir <path>— where the control DB and deploy directories live (default.pond-host).--anonymous-deploys/--no-anonymous-deploys— toggle unauthenticated deploys (default: on).--anonymous-grace <duration>— how long an unclaimed deploy stays alive (1h,30m,60s). Default1h.--anonymous-retention <duration>— how long after termination an unclaimed deploy stays on disk. Default7d.--anonymous-rate-per-hour <n>— rolling-hour rate limit per IP for anonymous deploys. Default5.--turnstile-secret <secret>— Cloudflare Turnstile secret. When set, anonymousPOST /api/deploysmust carry a verified Turnstile token (anx-pond-turnstile-tokenheader or aturnstileTokenbody field), checked against Cloudflare's siteverify. When unset (default) there is no challenge — dev/CI behaviour is unchanged. Authenticated deploys are never challenged. AlsoPOND_TURNSTILE_SECRET.--trust-proxy— read client IPs fromx-forwarded-for(you must terminate TLS yourself; otherwise this is spoofable). AlsoPOND_TRUST_PROXY_HEADERS=1.--abuse-email <addr>— contact shown on the/abuseand/securitypages.
# Local dev
pond host
# Production: bind all interfaces, public URL is HTTPS, abuse contact configured
pond host \
--host 0.0.0.0 \
--port 8787 \
--public-base-url https://pond.example.com \
--abuse-email abuse@example.com \
--trust-proxy
On Node 22 LTS and later, anonymous deploys boot inside Node's permission model — --allow-fs-read / --allow-fs-write scoped to the deploy dir. On Node 20 the sandbox is disabled and pond host warns about it. (0.2.6 fixed the Node-24 spelling regression here.)
pond admin terminate
Operator kill switch: stop a deploy's worker right now, gated by the host token. This is the manual companion to the grace-window sweeper — use it when a deploy is abusive and you don't want to wait for its TTL.
When to use: you operate the control plane and need to immediately take a specific deploy offline. For anonymous deploys it also marks the deploy terminated, so it stays down and the retention sweep deletes it on schedule. (To wipe the bytes immediately, DELETE /api/deploys/:id with the host token instead.)
Key flags:
<deployId>— the deploy to terminate (positional, required).--api <url>— control plane base URL, e.g.http://127.0.0.1:8787(required).--host-token <value>— the host token. Defaults toPOND_HOST_TOKEN.
# Using POND_HOST_TOKEN from the environment
POND_HOST_TOKEN=... pond admin terminate 1a2b3c4d5e6f7081 --api https://pond.example.com
# Or pass the token explicitly
pond admin terminate 1a2b3c4d5e6f7081 --api http://127.0.0.1:8787 --host-token <token>
pond login
Attach an existing user identity for a pond control plane. Saves the token to ~/.pond/credentials.json so subsequent pond deploy calls don't need a --token.
When to use: you already have a token issued to you (from a previous pond signup, an admin minting it for you, or a self-hosted bootstrap). For first-time account creation, use pond signup instead — it's a one-command path that doesn't require having a token in advance.
Key flags:
--api <url>— control plane base URL. Defaults tohttps://pond.run(matchespond deploy).--username <name>— label for the saved credential. With--token, must match the token's actual user.--token <value>— attach an existing token (the common path).--admin-token <value>— admin token, used to create a new (non-admin) user on a self-hosted plane. Requires--username.
# Attach an existing token (most common path)
pond login --username your-username --token usr_xxxxxxxx
# Self-hosted control plane
pond login --api https://pond.example.com --username your-username --token usr_xxxxxxxx
# Self-hosted bootstrap (POND_HOST_TOKEN must be set, or pass --admin-token)
POND_HOST_TOKEN=<bootstrap-token> pond login --api https://pond.example.com --username admin
When you don't have a token yet, pond login errors with a three-way hint:
pond signup <name>(if you have an anonymous deploy in this directory),pond login --token <token> --username <name>(if someone gave you a token),POND_HOST_TOKEN=…or--admin-token(self-hosted bootstrap).
pond dashboard
Open the per-host project dashboard in your browser. The dashboard is served by pond host at <host>/dashboard and lists every deploy owned by the signed-in user — project title, live URL, age, status (owned / shared / anonymous), plus per-deploy actions (Open IDE, Open live app, rotate claim token, delete). It's where you go after pond deploy to see "what have I shipped."
When to use: to see all your hosted projects in one place, jump into the IDE for any of them, or rotate a claim token after sharing a deploy.
Resolution order (so you rarely need to pass --api):
--api <url>if passed.apiUrlfrom.pond/deploy.jsonin the current directory.- The only saved credential in
~/.pond/credentials.json(if exactly one). - Otherwise: refuses with a list of
pond dashboard --api <url>invocations, one per saved credential.
Key flags:
--api <url>— pick a specific control plane.--print-url— print the URL instead of launching a browser. Use in headless / CI environments.
# Most common — opens whichever host this project deploys to
pond dashboard
# Pick a specific control plane
pond dashboard --api https://pond.run
# Headless / CI
pond dashboard --print-url --api https://pond.example.com
The dashboard authenticates with your account API token (the same one pond login saves to ~/.pond/credentials.json). The first visit asks you to paste it; subsequent visits remember it in localStorage.
pond user
Admin commands for users on a control plane.
pond user create [--admin]
Create a new user. Requires an admin token (loaded from ~/.pond/credentials.json or --token).
pond user create alice
pond user create bob --admin
pond user list
List users on the control plane.
pond user list
pond token
Manage the saved user API token.
pond token rotate --api
Rotate the saved token for an API. The new token replaces the old in ~/.pond/credentials.json.
pond token rotate --api https://pond.example.com
pond domains
Manage custom subdomains for hosted deploys. Bare pond domains now prints help cleanly (exit 0) instead of erroring with No command specified.
pond domains list --api
List subdomains configured for the authenticated user.
pond domains add --deploy --api
Attach a subdomain to a deploy. The subdomain becomes https://<subdomain>.<your-host>.
pond domains add my-app --deploy abc123 --api https://pond.example.com
pond domains remove --api
Detach a subdomain (the deploy keeps its <deployId>.<host> URL).
pond domains remove my-app --api https://pond.example.com
pond env
Manage env vars on a hosted deploy. They're written to the deploy's .env.pond.server and re-read on the next worker boot. Bare pond env now prints help cleanly (exit 0) instead of erroring with No command specified.
pond env list [deployId] --api
List env-var names (values are not returned).
pond env set KEY=value [KEY2=value2 …] --api
Set one or more env vars in a single call.
pond env set abc123 OPENAI_API_KEY=sk_… SENTRY_DSN=https://… --api https://pond.run
pond env unset KEY [KEY2 …] --api
Delete env vars.
pond env unset abc123 OLD_FLAG --api https://pond.run
pond auth
Manage the local dev-server guest identity. Useful only against pond dev — production deploys use real auth.
pond auth as --name
Set the current guest's display name so you can simulate a logged-in user without a real OAuth flow.
pond auth as --name your-username
Environment variables
A few useful ones:
| Variable | Purpose |
|---|---|
POND_SESSION_SECRET |
Persistent session-cookie secret. Set this in .env.pond.server for production; without it sessions don't survive a restart. |
POND_TRUST_PROXY_HEADERS |
Same effect as --trust-proxy on pond host. |
POND_PUBLIC_BASE_URL |
Same effect as --public-base-url on pond host. |
POND_TURNSTILE_SECRET |
Same effect as --turnstile-secret on pond host — requires a verified Cloudflare Turnstile token on anonymous deploys. |
POND_HOST_TOKEN |
The control-plane host token. Used by pond admin terminate and host bootstrap. |
See also
- Server API reference —
capsule(),table(),query(),mutation(),ctx.db, lifecycle. - Client API reference —
useQuery,useMutation,useAuth, sign-in helpers. - Operations guide — running
pond hostin production. - llms-full.txt — single-file dump of the agent-targeted docs.