CLI
The 9d9 CLI: push a directory, manage deploys, attach domains.
Install
No install needed for one-off use — npx grabs the latest:
npx @9d9dev/cli deploy ./dist For repeat use, install globally so the 9d9 command is always on PATH:
npm i -g @9d9dev/cli Authenticate
Generate an API key in your dashboard at Settings → New key. The secret is shown once. Save it locally:
9d9 set-key ak_xxx --org=org_xxx
Config is written to .9d9.json in the current directory.
Subsequent commands walk up from cwd to find it — so each repo gets its
own org binding. The file is local; add it to .gitignore.
Commands
9d9 deploy [dir]
Walks dir (defaults to .), uploads files in
parallel, commits a manifest, atomically activates the deploy.
- Skips dotfiles and
node_modules. - Content-hashes each file (sha256, first 16 hex chars) — used as the manifest fingerprint.
- Detects
404.htmland registers it as the deploy's not-found page. - Concurrency: 6 file uploads in flight.
- 25 MB per-file limit.
9d9 deploy ./dist
# Deploying 13 file(s), 127.2 KB total...
# Deploy dep_qXpgSbWcNGfoWy3PxJfE24Ls created.
# 10/13
# 13/13
#
# Active. Deploy dep_qXpgSbWcNGfoWy3PxJfE24Ls is live.
# https://your-slug.9d9.dev/ 9d9 deploys [list]
Lists recent deploys for the current site.
9d9 deploys
# active dep_qXpgSb... 13 files 2026-05-30T05:26:46.000Z
# superseded dep_DCAcX6... 4 files 2026-05-29T22:14:55.000Z 9d9 set-key <key> [--org=<org_id>]
Saves the API key and org ID locally.
9d9 status
Prints the current local config (token shown truncated).
9d9 logout
Clears local credentials.
Multiple sites on one machine
Each repo holds its own .9d9.json, so switching sites means
switching directories — no global state to forget about. For CI /
scripted use, override per-invocation with env vars:
NINEDENINE_API_KEY, NINEDENINE_API_URL.
Rolling back
The Deploys tab in the dashboard lists every deploy with an "Activate" button. Old deploys' files are preserved in R2 for 7 days. After that they're garbage-collected by a daily cron.