Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.deep.space/llms.txt

Use this file to discover all available pages before exploring further.

npx deepspace deploy builds your app and uploads it to Cloudflare Workers for Platforms, returning a live <name>.app.space URL.

What deploy does

The CLI builds your app with Vite (the Cloudflare plugin produces both the client bundle and the worker), validates your binding manifest, and uploads everything to the deploy worker as one request. From there, the platform auto-provisions any binding marked "auto", applies your user secrets from .dev.vars as secret_text bindings, and registers the worker in the dispatch namespace at <name>.app.space. Deploys are idempotent. Re-running deploy with no source changes reuses provisioned resources and uploads unchanged code as a no-op. See Build & deploy pipeline for the full step-by-step. Inspect deployed apps, logs, and traffic in the web dashboard at dashboard.deep.space.

Subdomains

The name field in wrangler.toml is your subdomain:
name = "my-app"
# → deploys to https://my-app.app.space
Rules:
  • Lowercase alphanumeric with optional dashes, up to 63 characters; cannot begin with a dash
  • Non-conforming names cause the CLI to fail with a clear error and the suggested canonical form; fix name in wrangler.toml and re-run
  • Renaming name after deploy and re-deploying gives you a new subdomain - the old one becomes orphaned (still accessible until explicitly undeployed)
To attach a real domain to your app, see Custom domains.

State preservation

A deploy does not wipe Durable Object state. Your records, conversations, files, and cron history persist across deploys. Survives a deploy:
  • Durable Object SQLite tables (records, Yjs documents, canvas state, cron history)
  • R2 bucket contents
  • Auto-provisioned bindings (D1, KV, Vectorize, etc.). Resource IDs are persisted and reused.
  • User secrets in .dev.vars. Re-uploaded each deploy; same values land as secret_text bindings.
Does not survive a deploy:
  • Worker module-level globals
  • In-memory caches inside DOs. Every DO restarts; persistent storage stays, in-memory state is rebuilt on the next request.

Schema migrations

The SDK runs additive schema migrations automatically. When a DO cold-starts after a deploy, the per-collection migrator creates any new tables and runs ALTER TABLE ADD COLUMN for new fields. Re-running with an unchanged schema is a no-op. Destructive changes are not handled: dropping a column, changing a column type, renaming a field, or backfilling data into a new shape. You’re responsible for any data migration before deploying a breaking schema change.

Secrets and .dev.vars

The CLI writes SDK-managed keys at the top of .dev.vars, followed by a divider, followed by anything you’ve added:
.dev.vars
AUTH_JWT_PUBLIC_KEY=...
AUTH_JWT_ISSUER=...
AUTH_WORKER_URL=...
API_WORKER_URL=...
PLATFORM_WORKER_URL=...
OWNER_USER_ID=...
APP_OWNER_JWT=...
APP_IDENTITY_TOKEN=...
INTERNAL_STORAGE_HMAC_SECRET=...
ALLOW_DEBUG_ROUTES=...

# --- not managed by the SDK; preserved across dev/test runs ---
STRIPE_SECRET_KEY=sk_test_...
OPENAI_API_KEY=sk-...
MY_FEATURE_FLAG=true
Anything below the divider:
  • Is preserved verbatim across dev / test / deploy runs
  • Becomes a secret_text binding on deploy (env.STRIPE_SECRET_KEY in worker code)
  • Never appears in compiled assets or client bundles
Never commit .dev.vars. The scaffold’s .gitignore covers it. To rotate a secret, edit the file and redeploy.

Secret constraints

LimitValue
Name pattern^[A-Za-z_][A-Za-z0-9_]*$
Per-value size32 KB
Total across all secrets128 KB
Raw deploy payload1 MB
Size limits are Cloudflare’s, enforced on secret_text bindings. Secret names cannot collide with any reserved binding name, custom binding, or Durable Object binding name. The CLI fails locally with a clear error before any upload.

Custom bindings

Add Vectorize, Workers AI, R2, KV, D1, Queues, Browser Rendering, Hyperdrive, or Analytics Engine bindings by declaring them in wrangler.toml. Set the ID to "auto" to auto-provision:
[[vectorize]]
binding = "VEC"
index_name = "auto"
dimensions = 768
metric = "cosine"

[[d1_databases]]
binding = "MY_DB"
database_id = "auto"
database_name = "my-app-db"
The deploy worker provisions the resource the first time you deploy, persists the ID, and reuses it on every subsequent deploy. See Custom bindings for the full list of types and gotchas.

Undeploy

To take an app down:
npx deepspace undeploy
This removes the subdomain registration, tears down auto-provisioned resources (with one exception), and cleans up bindings. The exception:
  • R2 buckets with files in them are not auto-deleted. This protects against accidental user-content loss. Empty the bucket manually if you want it gone.
Durable Object data is removed when the worker is undeployed. Back up anything you want to keep.

Before your first deploy

Three things to verify before shipping:
  • Finalize the app name. Renaming name in wrangler.toml later creates a new subdomain and orphans the old one.
  • Audit .dev.vars. Every key below the divider ships as a secret_text binding. Confirm prod credentials, not test keys.
  • Run npx deepspace test. Playwright runs your specs against a local build before you deploy them against the live one.

Next steps