Skip to content

CLI Commands

Both wrangler-deploy and the short alias wd are available after install. The CLI works for both new greenfield starters and existing Wrangler projects, so you can scaffold a fresh app or keep the wrangler.jsonc files you already have.

Scaffold a new Vite-style starter project that already includes a worker API, a local Vite frontend, and a wrangler-deploy.config.ts file. Use this when you are starting greenfield instead of adopting an existing repo.

Terminal window
$ wd create vite my-app
Created vite starter in /repo/my-app
package.json
tsconfig.json
vite.config.ts
index.html
src/main.ts
src/style.css
workers/api/src/index.ts
workers/api/wrangler.jsonc
wrangler-deploy.config.ts
README.md
.gitignore
  • wd create vite creates a starter in a new directory, defaulting to my-worker when you omit the directory
  • --name sets the package name and displayed project title
  • --force allows overwriting existing files in the target directory
  • --json returns the scaffold summary as machine-readable output

Scaffold a React + Vite + Workers starter. The CLI first attempts the official Cloudflare create-cloudflare React-on-Workers flow, then applies wrangler-deploy defaults (wrangler-deploy.config.ts and stage scripts). If the official flow cannot complete in the current environment, it falls back to the official cloudflare/templates React template.

Terminal window
$ wd create react my-react-app
Created react starter in /repo/my-react-app
package.json
vite.config.ts
wrangler.jsonc
worker/index.ts
src/main.tsx
src/App.tsx
wrangler-deploy.config.ts
  • wd create react is the recommended React starter path for Cloudflare Workers
  • the scaffold includes both direct deploy (deploy) and staged deploy scripts (plan, apply, status, deploy:stage)
  • use pnpm run deploy (not pnpm deploy) to run the deploy script under pnpm

wd context [get|set|unset|clear|doctor|export|import]

Section titled “wd context [get|set|unset|clear|doctor|export|import]”

Manage project-level defaults in a .wdrc or .wdrc.json file at or above the repo root. This is useful when you want to stop repeating the same stage, account, or dev settings on every command.

Terminal window
# Show everything (also runs as plain `wd context`)
$ wd context get
wrangler-deploy context
file: /repo/.wdrc
stage: "staging"
accountId: "1234567890abcdef1234567890abcdef"
# Read a single value
$ wd context get stage
wrangler-deploy context get
stage: "staging"
# Set defaults — merges into the nearest existing file or creates one
$ wd context set --stage staging --account-id 1234567890abcdef1234567890abcdef
wrangler-deploy context set
file: /repo/.wdrc
stage: "staging"
accountId: "1234567890abcdef1234567890abcdef"
# Remove specific keys
$ wd context unset --account-id
# Remove the file entirely
$ wd context clear

Subcommands:

  • wd context get [<key>] reads everything (no key) or a single value
  • wd context set --<key> <value> merges new defaults into .wdrc
  • wd context unset --<key> removes one or more keys
  • wd context clear removes the file entirely
  • wd context doctor shows the resolved values and where each came from (flag, env, .wdrc, default)
  • wd context export / wd context import --file <path> round-trip the config across machines
  • --json works for all subcommands

Valid keys: stage, fallbackStage, basePort, filter, session, persistTo, accountId, databaseUrl, statePassword, telemetry.

Scan your local Wrangler configs and generate wrangler-deploy.config.ts. Run this once when adopting wrangler-deploy in a repo that already has wrangler.jsonc or wrangler.json.

Terminal window
$ wd init
Generated wrangler-deploy.config.ts from /repo
Next:
wd context set --stage <name> Set default stage
wd plan Preview what will be created
wd apply Provision resources
wd deploy Deploy workers
wd status Verify everything is live

If no wrangler.jsonc files are found, the error suggests wd create vite <name> instead. Your checked-in Wrangler files are not modified.

wd introspect [--filter <prefix>] [--dry-run]

Section titled “wd introspect [--filter <prefix>] [--dry-run]”

Scan your live Cloudflare account and generate wrangler-deploy.config.ts from existing resources. Use this instead of init when you already have Workers and resources running in production.

If CLOUDFLARE_API_TOKEN is set, it discovers Workers and their bindings automatically. Without it, uses wrangler login credentials (but can’t fetch worker bindings).

Terminal window
# Pull everything from your account
$ wd introspect
Found 3 workers, 2 KV namespaces, 1 D1 database, 1 queue
Generated wrangler-deploy.config.ts
# Only resources starting with "payments-"
$ wd introspect --filter payments-
# Preview without writing the file
$ wd introspect --dry-run

Dry-run. Shows what resources would be created, are in sync, drifted, or orphaned. Run this before apply to preview changes.

Terminal window
$ wd plan --stage pr-42
wrangler-deploy plan --stage pr-42
+ payments-db-pr-42 (d1) create
+ token-kv-pr-42 (kv) create
+ cache-kv-pr-42 (kv) create
+ payment-outbox-pr-42 (queue) create
+ payment-outbox-dlq-pr-42 (queue) create
5 to create, 0 in sync, 0 drifted, 0 orphaned

wd apply --stage <name> [--database-url <url>]

Section titled “wd apply --stage <name> [--database-url <url>]”

Provision resources in Cloudflare. This step is idempotent, so it is safe to run again if it fails partway through. State is written after each resource, and deploy-time wrangler.rendered.jsonc files are generated with the real IDs for that stage.

Terminal window
$ wd apply --stage pr-42
+ creating payments-db-pr-42 (d1)...
created (id: ad7171e9-118a-409c-8a0f-7383e823a098)
+ creating token-kv-pr-42 (kv)...
created (id: a83b9d510419478fbd9f99c8ccca7388)
+ creating cache-kv-pr-42 (kv)...
created (id: d5ce65080cd44fe196ffcd6a222ff9a0)
+ creating payment-outbox-pr-42 (queue)...
created
+ creating payment-outbox-dlq-pr-42 (queue)...
created
─── pr-42 apply summary ───
Created (5):
+ payments-db-pr-42 (d1, id: ad7171e9-…)
+ token-kv-pr-42 (kv, id: a83b9d…)
+ cache-kv-pr-42 (kv, id: d5ce65…)
+ payment-outbox-pr-42 (queue)
+ payment-outbox-dlq-pr-42 (queue)
Workers ready for deploy (3):
workers/api-pr-42
workers/batch-workflow-pr-42
workers/event-router-pr-42
Rendered configs:
.wrangler-deploy/pr-42/workers/api/wrangler.rendered.jsonc
.wrangler-deploy/pr-42/workers/batch-workflow/wrangler.rendered.jsonc
.wrangler-deploy/pr-42/workers/event-router/wrangler.rendered.jsonc
State: .wrangler-deploy/pr-42/state.json
Next:
- wd deploy --stage pr-42
- wd status --stage pr-42

--database-url is required for Hyperdrive on first apply (it needs a Postgres connection string). Re-running apply against an already-deployed stage preserves the per-worker deployed/url state recorded by the last wd deploy.

Deploy workers using rendered configs with real resource IDs. Workers are deployed in dependency order, so service-binding targets go first. Deploy blocks if declared secrets are missing.

Terminal window
$ wd deploy --stage pr-42
deploying payment-batch-workflow-pr-42...
Uploaded payment-batch-workflow-pr-42 (5.2 sec)
Deployed payment-batch-workflow-pr-42 triggers (3.1 sec)
https://payment-batch-workflow-pr-42.you.workers.dev
Current Version ID: 3519f525-…
deploying payment-api-pr-42...
Uploaded payment-api-pr-42 (9.2 sec)
Deployed payment-api-pr-42 triggers (5.6 sec)
https://payment-api-pr-42.you.workers.dev
Current Version ID: 32f94f3c-…
deploying payment-event-router-pr-42...
Uploaded payment-event-router-pr-42 (8.1 sec)
Deployed payment-event-router-pr-42 triggers (11.4 sec)
https://payment-event-router-pr-42.you.workers.dev
Current Version ID: b401672b-…
─── pr-42 deployment summary ───
payment-batch-workflow-pr-42
Status: deployed
Version: 3519f525-…
URL: https://payment-batch-workflow-pr-42.you.workers.dev
Dashboard: https://dash.cloudflare.com/<acct>/workers/services/view/payment-batch-workflow-pr-42
payment-api-pr-42
Status: deployed
Version: 32f94f3c-…
URL: https://payment-api-pr-42.you.workers.dev
Dashboard: https://dash.cloudflare.com/<acct>/workers/services/view/payment-api-pr-42
payment-event-router-pr-42
Status: deployed
Version: b401672b-…
URL: https://payment-event-router-pr-42.you.workers.dev
Dashboard: https://dash.cloudflare.com/<acct>/workers/services/view/payment-event-router-pr-42
Next:
- wd status --stage pr-42
- wd open --stage pr-42 --worker workers/api
- wd dashboard --stage pr-42 --worker workers/api

--verify runs post-deploy coherence checks and fails the pipeline if anything is wrong. --changed scopes deploy to git-changed workers; --latest is the default-worker hint for open/dashboard.

Tear down all resources for a stage. Removes queue consumers first, then workers, then resources — in the right order. Requires --force for protected stages.

Terminal window
$ wd destroy --stage pr-42
Removing queue consumers...
Deleting workers...
Deleting resources...
Stage "pr-42" destroyed

Show resources, workers, and deployment URLs for a stage. With no --stage it falls back to your $USER default.

Terminal window
$ wd status --stage staging
Stage: staging
Created: 2026-05-14T19:14:48.621Z
Updated: 2026-05-14T19:16:49.581Z
Resources:
+ payments-db-staging (d1) — created
+ token-kv-staging (kv) — created
+ outbox-staging (queue) — created
Workers:
payment-api-staging https://payment-api-staging.you.workers.dev
payment-batch-workflow-staging https://payment-batch-workflow-staging.you.workers.dev

Flags:

  • --json / --output json|ndjson for machine consumers (full state shape including deploymentHistory)
  • --summary for one-line stage workers=N deployed=N resources=N format
  • --watch [--interval-ms <ms>] to poll for changes
  • --fail-on-drift to exit non-zero when state and live resources diverge
  • --web to open the stage in wd dev ui

Resolve and open the deployed URL for a worker. With more than one worker, prompts interactively (or pass --latest to use the last-deployed one).

Terminal window
$ wd open --stage staging --worker workers/api
Opening https://payment-api-staging.you.workers.dev...
$ wd open --stage staging --worker workers/api --print-url
https://payment-api-staging.you.workers.dev
$ wd open --stage staging --worker workers/api --copy
Copied https://payment-api-staging.you.workers.dev

wd dashboard --stage <name> [--worker <path>]

Section titled “wd dashboard --stage <name> [--worker <path>]”

Like wd open, but jumps to the worker’s Cloudflare dashboard page. Same --print-url / --copy / --latest flags.

Workers usage guard commands. These are split into:

  • status: direct Cloudflare GraphQL usage view (requires CLOUDFLARE_API_TOKEN)
  • init|deploy|migrate: provision and deploy the workers-usage-guard Worker package
  • breaches|report|disarm|arm|approvals|approve|reject: require a deployed guard endpoint and WRANGLER_DEPLOY_GUARD_SIGNING_KEY

Show current usage for accounts defined in guard.accounts in wrangler-deploy.config.ts.

Terminal window
$ CLOUDFLARE_API_TOKEN=... wd guard status

wd guard init --account <id> [--billing-cycle-day <1-31>] [--workers <names>] [--database-id <id>] [--yes]

Section titled “wd guard init --account <id> [--billing-cycle-day <1-31>] [--workers <names>] [--database-id <id>] [--yes]”

One-command setup: creates the D1 database, applies migrations, sets secrets, and deploys workers-usage-guard. Prints the config snippet to add to wrangler-deploy.config.ts.

Terminal window
$ wd guard init --account 1234abcd --workers api,event-router --yes

Prompts for notification channels interactively (skip with --yes).

  • --workers — comma-separated worker script names to monitor
  • --database-id — skip D1 creation and use an existing database (re-init safe)
  • --billing-cycle-day — day of month the billing cycle starts (default: 1)
  • --yes — non-interactive; skip all prompts

Re-deploy workers-usage-guard using guard.databaseId from config (or --database-id).

Terminal window
$ wd guard deploy
$ wd guard deploy --database-id bd0274ea-ea3b-4fd7-966d-ee55d6ce9947

Apply D1 migrations to the guard database. Uses guard.databaseId from config (or --database-id).

Terminal window
$ wd guard migrate

wd guard breaches --account <id> [--limit <n>] [--json]

Section titled “wd guard breaches --account <id> [--limit <n>] [--json]”

Read recent breach forensics from the guard API.

Terminal window
$ wd guard breaches --account 1234abcd --limit 10

wd guard report --account <id> [--date <YYYY-MM-DD>] [--json]

Section titled “wd guard report --account <id> [--date <YYYY-MM-DD>] [--json]”

Read daily usage report data from the guard API.

Terminal window
$ wd guard report --account 1234abcd
$ wd guard report --account 1234abcd --date 2026-04-19

The guard API also exposes /api/snapshots with window=<n>d|<n>h (for example window=7d or window=24h) and validates this format server-side.

wd guard disarm <script> --account <id> [--reason <text>]

Section titled “wd guard disarm <script> --account <id> [--reason <text>]”

Toggle runtime protection for a worker script (human override on kill-switch behavior).

Terminal window
$ wd guard disarm payment-api --account 1234abcd --reason "incident mitigation"
$ wd guard arm payment-api --account 1234abcd

wd guard approvals --account <id> [--json]

Section titled “wd guard approvals --account <id> [--json]”

wd guard approve <approval-id> --account <id>

Section titled “wd guard approve <approval-id> --account <id>”

wd guard reject <approval-id> --account <id>

Section titled “wd guard reject <approval-id> --account <id>”

List and decide pending human approvals created by the kill-switch workflow.

Terminal window
$ wd guard approvals --account 1234abcd
$ wd guard approve appr-123 --account 1234abcd
$ wd guard reject appr-456 --account 1234abcd

workers-usage-guard ships a standalone CLI for teams that run the guard service without wrangler-deploy. The binary is published as both wug and workers-usage-guard. All commands read endpoint and signing key from wug.config.json (in the current directory) or from $WUG_ENDPOINT / $GUARD_API_SIGNING_KEY / flags.

The fastest way in:

Terminal window
$ npx workers-usage-guard setup

wug setup [--account <id>] [--scripts <a,b,c>] [--api-token <token>] [--yes]

Section titled “wug setup [--account <id>] [--scripts <a,b,c>] [--api-token <token>] [--yes]”

End-to-end install: create D1, generate signing key, write wug.config.json, apply migrations, deploy the Worker, set required secrets, and poll /api/health. Pass --yes for non-interactive (CI) installs — every required value must then be a flag or env var.

Terminal window
$ wug setup --yes \
--account 1234abcd \
--scripts payment-api,event-router \
--api-token $CLOUDFLARE_API_TOKEN

wug init --account <id> [--script-name <name>] [--billing-cycle-day <1-31>] [--force]

Section titled “wug init --account <id> [--script-name <name>] [--billing-cycle-day <1-31>] [--force]”

Write a minimal wug.config.json without provisioning anything. Useful when you want to inspect/edit the config before running wug setup.

Print a fresh 32-byte hex signing key. Set as $GUARD_API_SIGNING_KEY. Never store the key in wug.config.json.

Validate wug.config.json, environment variables, and (if endpoint is reachable) /api/health. Exits non-zero on any failure.

Pre-deploy checks: confirms wrangler is authed and lists any required Worker secrets that are not yet set. Run between wug setup and wug deploy when iterating.

Apply D1 migrations bundled with the package against the database referenced in wug.config.json. --remote by default; --local for the D1 emulator.

Render a wrangler config from your wug.config.json and run wrangler deploy against the package’s compiled Worker. Stores the deployed endpoint back in wug.config.json on success.

Delete the deployed Worker. With --keep-data, leaves the D1 database in place; otherwise also deletes the configured database. Always prompts unless --yes.

Call /api/health (unsigned). Reads endpoint from flag, $WUG_ENDPOINT, or wug.config.json.

Tail logs from the deployed guard via wrangler tail.

All operational commands are signed; they need $GUARD_API_SIGNING_KEY (or --signing-key). All support --json.

Terminal window
wug breaches [--account <id>] [--limit <n>]
wug report [--account <id>] [--date YYYY-MM-DD]
wug snapshots --script <name> [--account <id>] [--window <Nd|Nh>]
wug disarm <script> [--account <id>] [--reason <text>]
wug arm <script> [--account <id>]
wug approvals [--account <id>]
wug approve <approval-id> [--account <id>]
wug reject <approval-id> [--account <id>]
wug runtime-protected [--account <id>]

Print every secret the guard will need (always-required + per-notification-channel), derived from wug.config.json.

wug diff-config --before <file> --after <file> [--json]

Section titled “wug diff-config --before <file> --after <file> [--json]”

Compare two ACCOUNTS_JSON snapshots (or two wug.config.json files). Reports added/removed accounts, added/removed workers, and threshold changes.

For each configured account, list scripts the guard could detach (killable) versus those it cannot (protected). Use before changing protection rules.

Run a non-destructive safety simulation before deploy/policy changes:

  • missing required secrets
  • killable vs protected scripts
  • low-threshold/forecast-noise warnings

Exits non-zero if blockers are found, so it can gate CI.

wug sign --method <verb> --path <path> [--key <secret>] [--timestamp <iso>]

Section titled “wug sign --method <verb> --path <path> [--key <secret>] [--timestamp <iso>]”

Generate x-guard-timestamp and x-guard-signature headers for a manual curl call.

Read-only coherence check. Validates state against live resources, rendered configs, workers, secrets, and service bindings. Use this in CI after deploy, or manually to check if everything is still consistent. Each check appears on its own line so failures point at the specific resource:

Terminal window
$ wd verify --stage staging
wrangler-deploy verify --stage staging
+ State file exists
+ Rendered config: workers/api
+ Rendered config: workers/batch-workflow
+ Resource: payments-db-staging
+ Resource: token-kv-staging
+ Resource: outbox-staging
+ Manifest resource in state: payments-db
+ Manifest resource in state: token-kv
+ Manifest resource in state: outbox
+ Worker registered: workers/api payment-api-staging
+ Worker registered: workers/batch-workflow payment-batch-workflow-staging
+ Service binding: workers/api.WORKFLOWS -> workers/batch-workflow
12 passed, 0 failed

Run a config-driven local smoke test against the active development runtime.

Terminal window
$ wd verify local
wrangler-deploy verify local
+ api health 200 http://127.0.0.1:8791/health
+ reset payments db workers/api
+ seed payments db workers/api
+ seeded batch count workers/api
+ payment outbox accepts payloads 200 http://127.0.0.1:8791/__wd/queues/payment-outbox
+ batch workflow cron route 200 http://127.0.0.1:8787/cdn-cgi/handler/scheduled
6 passed, 0 failed

This is the repo-aware local harness. It can combine:

  • worker endpoint checks
  • cron triggers
  • queue sends
  • local D1 reset, seed, and SQL assertions
  • named verify packs for CI-style smoke and regression runs
  • machine-readable JSON output with --json-report

Configure it with verifyLocal.checks in wrangler-deploy.config.ts, then run it after wd dev.

Use --pack <name> when you want a named subset or stricter regression pack:

Terminal window
$ wd verify local --pack smoke

Use --json-report in CI when you want structured output:

Terminal window
$ wd verify local --pack regression --json-report

Check which declared secrets are set or missing. Use before deploy to see what’s needed.

Terminal window
$ wd secrets --stage staging
workers/api:
AUTH_SECRET set
API_KEY missing

Set missing secrets interactively. Prompts for each missing value.

Terminal window
$ wd secrets set --stage staging
workers/api / API_KEY: ****
1 secret set

wd secrets sync --to <name> --from-env-file <path>

Section titled “wd secrets sync --to <name> --from-env-file <path>”

Bulk set secrets from a .dev.vars-style file. Useful for syncing local dev secrets to a staging environment.

Terminal window
$ wd secrets sync --to staging --from-env-file .dev.vars
Synced 3 secrets to staging

Destroy stages past their TTL. Only affects unprotected stages. Typically run on a daily cron in CI to clean up old PR preview environments.

Terminal window
$ wd gc
pr-38 expired (7d TTL, created 2026-03-28) — destroying
pr-39 expired (7d TTL, created 2026-03-29) — destroying
2 stages destroyed

wd graph [--stage <name>] [--format ascii|mermaid|dot|json]

Section titled “wd graph [--stage <name>] [--format ascii|mermaid|dot|json]”

Show the topology graph. Default format is ascii. Use when you want to see how workers, resources, and bindings connect.

Terminal window
$ wd graph
[worker] api
├── (binding: DB) [d1] payments-db
├── (binding: TOKEN_KV) [kv] token-kv
├── (producer: OUTBOX_QUEUE) [queue] payment-outbox
└── (service-binding: WORKFLOWS) [worker] batch-workflow
[worker] batch-workflow
├── (binding: DB) [d1] payments-db
├── (binding: CACHE_KV) [kv] cache-kv
└── (producer: OUTBOX_QUEUE) [queue] payment-outbox
[worker] event-router
├── (binding: DB) [d1] payments-db
├── (producer: OUTBOX_QUEUE) [queue] payment-outbox
└── (consumer) [queue] payment-outbox
[queue] payment-outbox
└── (dead-letter) [queue] payment-outbox-dlq

Mermaid output you can paste into a PR comment:

Terminal window
$ wd graph --format mermaid
graph TD
subgraph Workers
workers_api([api])
workers_batch_workflow([batch-workflow])
workers_event_router([event-router])
end
subgraph Queues
payment_outbox[/payment-outbox\]
payment_outbox_dlq[/payment-outbox-dlq\]
end
workers_api -->|WORKFLOWS| workers_batch_workflow
workers_api -->|OUTBOX_QUEUE| payment_outbox
payment_outbox -. DLQ .-> payment_outbox_dlq

When --stage is provided, overlays live state (resource IDs, worker URLs, sync status).

Show what depends on a worker and what breaks if it goes down. Run this before making breaking changes.

Terminal window
$ wd impact workers/api
Impact analysis for workers/api
Upstream (depends on):
payments-db shared with workers/batch-workflow, workers/event-router
token-kv exclusive
payment-outbox shared with workers/batch-workflow, workers/event-router
If workers/api is unavailable:
workers/batch-workflow is unaffected (no direct dependency)
workers/event-router is unaffected (no direct dependency)

wd diff <stage-a> <stage-b> [--format json]

Section titled “wd diff <stage-a> <stage-b> [--format json]”

Compare two stages side by side. Use before promoting staging to production, or to audit what a PR preview added.

Terminal window
$ wd diff staging production
Diff: staging vs production
Resources:
= payments-db (d1) — same
+ cache-kv (kv) — only-in-a
~ token-kv (kv) — different
Workers:
= workers/api same
+ workers/experiment only-in-a

--format json for machine-readable output you can pipe into other tools.

wd dev [--stage <stage>] [--filter <worker>] [--port <base>] [--session] [--persist-to <path>]

Section titled “wd dev [--stage <stage>] [--filter <worker>] [--port <base>] [--session] [--persist-to <path>]”

Start all workers in local dev mode. Reads your existing wrangler.jsonc files as-is, or uses the rendered stage configs when you pass --stage. Automatically resolves available dev and inspector ports so multi-worker setups work without conflicts.

--stage is the normal way to make local dev line up with a stage you already applied. wrangler.jsonc remains the thing you author and keep in the repo. --remote is not the primary wrangler-deploy path.

Wrangler can start these workers too. The benefit of wd dev is that it derives the worker set, dependency order, port map, companion processes, and session settings from one project config instead of leaving that orchestration to shell scripts or tribal knowledge.

Terminal window
$ wd dev
Starting dev servers:
workers/api -> http://localhost:8787
workers/batch-workflow -> http://localhost:8788
workers/event-router -> http://localhost:8789

--filter starts only the target worker and its transitive service-binding deps. Use when you only need part of the system running:

Terminal window
$ wd dev --filter workers/api
Starting dev servers:
workers/batch-workflow -> http://localhost:8787
workers/api -> http://localhost:8788

(batch-workflow is included because api has a service binding to it.)

If you already ran wd apply --stage staging, then wd dev --stage staging uses the rendered stage configs directly. That keeps local bindings aligned with deploy-time bindings, including D1, KV, R2, queue, and service bindings.

Use --session for Cloudflare Queue local development sessions where producer and consumer workers need to share one Miniflare environment:

Terminal window
$ wd dev --stage staging --session --persist-to .wrangler/state
Starting local dev session:
workers/api -> http://localhost:8787
includes: workers/batch-workflow, workers/event-router

--persist-to also enables session mode even if --session is omitted.

Run local preflight checks before starting a dev stack. This validates worker config files, session entry worker references, companion working directories, cron-enabled workers, and queue topology wiring.

Terminal window
$ wd dev doctor
wrangler-deploy dev doctor
dev worker config: workers/api: wrangler config found
dev worker config: workers/batch-workflow: wrangler config found
cron route: workers/batch-workflow: 1 cron trigger(s) configured
dev session entry worker: workers/api is declared

Use this when wd dev behaves strangely or when you want to catch local-only config problems before you start anything.

Start a small local control plane for the active runtime.

Terminal window
$ wd dev ui --port 8899
dev ui -> http://127.0.0.1:8899

The UI shows worker URLs, named endpoints, queue topology, D1 databases, verify packs, snapshots, recent history, logs, resolved project defaults, and agent metadata. It also lets you:

  • call named local endpoints
  • run fixture-backed worker, queue, and D1 actions
  • trigger cron workers
  • run local verify packs with pass/fail summaries
  • save and load local snapshots
  • replay recent local actions from the UI history

The top of the dashboard includes the same .wdrc / .wdrc.json defaults and command manifest information exposed by wd context, wd schema, and wd tools.

Use this when you want the repo-aware runtime workflow without memorizing commands during local debugging.

Trigger a local scheduled event against a running wrangler dev server. This calls Cloudflare’s documented local scheduled route: /cdn-cgi/handler/scheduled.

Terminal window
$ wd cron trigger workers/batch-workflow --port 8787
200 http://127.0.0.1:8787/cdn-cgi/handler/scheduled
ok

Optional flags:

  • --cron "<expr>" to override controller.cron
  • --time <epoch> to override controller.scheduledTime
  • --path <route> to override the default scheduled route
  • --port <number> to target an explicit local dev port

Repeat local scheduled events on an interval. Useful for replaying cron-driven workflows or local recovery loops.

Terminal window
$ wd cron loop workers/batch-workflow --port 8787 --every 5s --cron "*/5 * * * *"

Intervals accept ms, s, or m suffixes.

List saved local runtime snapshots.

Terminal window
$ wd snapshot list
Snapshots
local-baseline
created: 2026-04-07T19:02:26.117Z
sources: .wrangler/state, .wrangler/state/v3, .wrangler-deploy/dev-runtime.json, .wrangler-deploy/dev-logs

Save the current local state so it can be restored later.

Terminal window
$ wd snapshot save local-baseline

This snapshots the configured local Miniflare state plus runtime metadata and logs. It is meant for reproducible local environments, not as a replacement for wrangler.jsonc.

Restore a previously saved local runtime snapshot.

Terminal window
$ wd snapshot load local-baseline

Use this when you want to jump back to a known-good D1 and local resource state before rerunning wd verify local or replaying queue traffic.

Call a running local worker by worker path instead of remembering the current port yourself.

This is the HTTP equivalent of wd queue send: Wrangler can expose the worker, but wd worker call resolves the current local port from the repo’s active dev runtime or planned dev config first.

Terminal window
$ wd worker call workers/api --method POST --path /__wd/echo --query source=docs --header x-request-id=local-test --json '{"ping":true}'
worker workers/api
POST http://127.0.0.1:8788/__wd/echo?source=docs
200
{"ok":true,"worker":"api","method":"POST","path":"/__wd/echo","query":{"source":"docs"},"requestId":"local-test","body":"{\"ping\":true}"}

Or call a shared fixture:

Terminal window
$ wd worker call --fixture echo-ping

Optional flags:

  • --method <verb> to override the default GET
  • --path <route> to call a non-root route
  • --query key=value to append query-string pairs, repeatable
  • --header key=value to send request headers, repeatable
  • --json '<payload>' to send a JSON body and default content-type: application/json
  • --body '<text>' to send a raw body
  • --body-file request.txt to read the request body from disk
  • --watch to repeat the call on an interval
  • --every 5s to control the watch interval
  • --count 10 to stop after a fixed number of calls
  • --port <number> to force a specific local dev port
  • --fixture <name> to load a shared worker fixture from config
  • --json, --body, and --body-file are mutually exclusive

Start wd dev first if you want the command to use the active runtime’s current ports automatically.

Show the current local URL for each worker plus any named endpoints declared in dev.endpoints.

Terminal window
$ wd worker routes workers/api
Worker routes
workers/api
url: http://127.0.0.1:8788
endpoint health: GET /health
endpoint echo: POST /__wd/echo

This is the discovery command for wd worker call. Use it when you want to see the repo’s local HTTP surface without opening multiple wrangler.jsonc files.

Tail persisted logs from the active wd dev runtime.

Terminal window
$ wd logs workers/api --once
Tailing dev logs
[workers/api]
[wrangler:info] GET /health 200 OK (5ms)

Optional flags:

  • --once to print the current snapshot and exit
  • --every 1s to change the polling interval
  • --grep <pattern> to filter by regex

This is broader than wd queue tail: it tails a worker’s full persisted runtime log instead of only queue-related lines.

Show D1 database topology from wrangler-deploy.config.ts.

Terminal window
$ wd d1 list
D1 databases
payments-db
bindings: workers/api:DB, workers/batch-workflow:DB, workers/event-router:DB

Inspect one logical D1 database in detail, including any configured seed or reset files.

Terminal window
$ wd d1 inspect payments-db
D1: payments-db
bindings: workers/api:DB, workers/batch-workflow:DB, workers/event-router:DB
seed file: sql/seed.sql
reset file: sql/reset.sql
default worker: workers/api

Run wrangler d1 execute --local by logical database name instead of by manually choosing a worker directory first.

Terminal window
$ wd d1 exec payments-db --sql 'SELECT COUNT(*) AS batch_count FROM batches;'
$ wd d1 exec --fixture payments-batch-count

Use one of:

  • --sql 'SELECT ...'
  • --file sql/query.sql
  • --fixture <name>

If the database is bound in multiple workers, configure dev.d1["<database>"].worker or pass --worker.

Run a local seed SQL file for a logical D1 database.

Terminal window
$ wd d1 seed payments-db

This uses dev.d1["payments-db"].seedFile by default, or --file when you want to override it for one run.

Run a local reset SQL file for a logical D1 database.

Terminal window
$ wd d1 reset payments-db

This is intentionally explicit. wrangler-deploy does not guess how to reset your schema. It runs the SQL file you configure in dev.d1["payments-db"].resetFile or pass with --file.

Show queue topology from wrangler-deploy.config.ts, including producers, consumers, and dead-letter relationships.

Terminal window
$ wd queue list
Queue topology
payment-outbox
producers: workers/api:OUTBOX_QUEUE, workers/batch-workflow:OUTBOX_QUEUE
consumers: workers/event-router
payment-outbox-dlq dead-letter for payment-outbox
producers: none
consumers: none

Inspect one queue in detail.

Terminal window
$ wd queue inspect payment-outbox
Queue: payment-outbox
producers: workers/api:OUTBOX_QUEUE, workers/batch-workflow:OUTBOX_QUEUE
consumers: workers/event-router
dead-letter-for: none

Send a local queue payload through a producer worker’s debug route. This avoids undocumented Miniflare internals and uses the worker’s real Queue binding.

Raw Wrangler does not give you a repo-level “send to this logical queue” workflow. wd queue send resolves the correct producer worker, current local port, and configured route from your project config first.

Terminal window
$ wd queue send payment-outbox --json '{"type":"batch.dispatched","data":{"batchId":"local-test"}}'
$ wd queue send --fixture payment-outbox-dispatch
queue payment-outbox -> workers/api
200 http://127.0.0.1:8788/__wd/queues/payment-outbox
{"queued":true}

Use one of:

  • --json '<payload>'
  • --file payload.json
  • --fixture <name>

Optional flags:

  • --watch to repeat the same payload on an interval
  • --every 5s to control the watch interval
  • --count 10 to stop after a fixed number of sends
  • --worker <worker> when a queue has multiple producers and you want a specific one
  • --port <number> to target a specific local dev port
  • --path <route> to override the configured local injection route

If a queue has multiple producers, configure dev.queues in wrangler-deploy.config.ts or pass --worker.

Show the shared local fixtures declared in wrangler-deploy.config.ts.

Terminal window
$ wd fixture list
Fixtures
api-health [worker]
workers/api endpoint=health
payment-outbox-dispatch [queue]
payment-outbox via workers/api
payments-batch-count [d1]
payments-db via workers/api sql

This is the discovery command for fixture-backed local workflows. Use it when you want reusable worker calls, queue sends, D1 queries, and local verification steps to all share the same inputs.

Replay a fixture file containing a JSON array of queue payloads.

Terminal window
$ wd queue replay payment-outbox --file fixtures/payment-outbox.json
replay payment-outbox -> workers/api
sent 2 message(s) to http://127.0.0.1:8788/__wd/queues/payment-outbox
all messages accepted

The file must contain a top-level JSON array. Each array element is POSTed as one queue payload through the same local producer route used by wd queue send.

Tail queue-related logs from the active wd dev runtime. This reads persisted per-worker dev logs written by wd dev and shows queue markers or local injection route activity.

This is another app-level workflow wrapper. Wrangler gives you process logs, but not a logical “tail queue activity for this app” command.

Terminal window
$ wd queue tail payment-outbox --once
Tailing queue payment-outbox
[workers/api]
[wrangler:info] POST /__wd/queues/payment-outbox 200 OK (9ms)

Use:

  • --once to print the current snapshot and exit
  • --every 1s to change the polling interval
  • --worker <worker> to restrict tailing to one related worker

Start wd dev first so runtime state and log files exist.

wd ci init [--provider github] [--branch main]

Section titled “wd ci init [--provider github] [--branch main]”

Generate a GitHub Actions workflow. Run this once to set up CI/CD for your project.

Terminal window
$ wd ci init
Generated .github/workflows/wrangler-deploy.yml

The generated workflow includes apply, deploy, PR comments, check runs, cleanup on PR close, production deploy on push to main, and the right GitHub token permissions.

Post or update a PR comment with worker URLs, topology diagram, resource tables, and secret status. Uses <!-- wrangler-deploy --> to update the same comment on each push. Requires GITHUB_TOKEN.

Post a GitHub check run with success/failure status. If no state exists for the stage, the check reports failure and the command exits 1 — so your CI pipeline fails instead of passing silently. Requires GITHUB_TOKEN.

Run diagnostic checks. Use when setting up a new project, after upgrading wrangler, or when CI fails unexpectedly. Safe to run in a directory without a wrangler-deploy.config.ts — it just reports what’s missing.

Terminal window
$ wd doctor
wrangler-deploy doctor
wrangler installed: wrangler 4.88.0
wrangler auth: you@example.com (account Your Account)
worker path: workers/api: workers/api exists
worker path: workers/batch-workflow: workers/batch-workflow exists
worker path: workers/event-router: workers/event-router exists
config valid: No config errors

In an empty directory, doctor surfaces the missing config with a warning rather than failing:

Terminal window
$ wd doctor
wrangler installed: wrangler 4.88.0
wrangler auth: you@example.com (account Your Account)
wrangler-deploy config: no wrangler-deploy.config.ts found in this directory
Run `wd create vite <name>` to scaffold a starter, or `wd init` if you already have wrangler.jsonc files.

Flags:

  • --codes adds a WD_DOC_* code alongside each check (useful in --json for agents)
  • --strict exits non-zero on any warning
  • --fix writes safe defaults (accountId from env, default stage in .wdrc)
  • --fix-dry-run shows what --fix would do without writing
  • --json returns the full check list as a structured envelope

Guided remediation for WD_E_* codes and common error messages. Run with no argument to see the full catalogue.

Terminal window
$ wd explain WD_E_STATE_MISSING
explain: WD_E_STATE_MISSING
The target stage has not been provisioned yet.
- Run `wd apply --stage <name>` to create stage resources and rendered configs.
- Run `wd status` to list available stages.
- Set a default via `wd context set --stage <name>` to avoid repeats.

Flags:

  • --from-last-error explains the most recent failure (.wrangler-deploy/last-error.json)
  • --error-code <code> is an alias for passing a code positionally
  • --json returns the explanation as a structured envelope

Every command failure prints a hint like Run wd explain WD_E_STATE_MISSING for more detail, so you can jump straight here.

See the Profiles guide for the full flow. Quick reference:

Terminal window
wd configure --profile prod # set up account metadata for a profile
wd login --profile prod # save Cloudflare API token for a profile
wd logout --profile prod [--purge] # delete the credential file (and config entry)
wd profile list # active profile + every configured one

Print the required Cloudflare API token scopes plus a deeplink to the dashboard’s token-creation page with the right scopes pre-selected.

Terminal window
wd util create-cf-token --profile prod # prints scopes + URL
wd util scopes # just the scope table

Inspect what’s in state without parsing JSON. See State Inspection.

Terminal window
wd state list --stage staging
wd state get cache --stage staging
wd state tree --stage staging

Read-only: validate config, summarise current deploy state, exit. Useful in CI before any mutating command.

Terminal window
wd run --stage staging

Spawn a Cloudflare Quick Tunnel in front of one or all running workers.

Terminal window
wd dev --tunnel # tunnel every worker
wd dev --tunnel workers/api # only one

Drop wrangler-deploy guidance for AI agents into editor-specific paths.

Terminal window
wd create vibe-rules claude-code,cursor # specific targets
wd create vibe-rules all # everything (claude-code, cursor,
# windsurf, vscode, zed, codex,
# agents-md)

Pass --force to overwrite existing files.

Print the installed version. With --json, returns full binary metadata for agents:

{
"package": "wrangler-deploy",
"version": "1.4.4",
"manifestVersion": 1,
"binaryPath": "/usr/local/bin/wd",
"node": "v24.12.0",
"platform": "darwin",
"arch": "arm64",
"sandbox": false,
"timestamp": "2026-05-14T20:33:59.526Z"
}

wd schema [outputs|config|errors] [--versioned] [--command <name>]

Section titled “wd schema [outputs|config|errors] [--versioned] [--command <name>]”

The agent discovery surface — see I/O and schemas for the full agent-facing story.

Terminal window
wd schema --json # full CLI manifest
wd schema --versioned --json # manifest + outputs + config in one envelope
wd schema outputs --json # output schemas for every JSON-emitting command
wd schema outputs --command deploy --json # output schema for one command
wd schema outputs --command devEvent --json # NDJSON event schema for `wd dev --json`
wd schema config --json # JSON Schema for wrangler-deploy.config.ts
wd schema errors --json # error envelope schema + WD_E_* codes

Compact metadata view derived from the manifest. One entry per command with name, description, mutating, output, flags, subcommands. Designed for agents that want to register every command as a tool without parsing the full manifest.

Copy-pasteable example invocations for a command. Without --command, lists every command that has examples.

Terminal window
wd examples --json
wd examples --command deploy --json

Each set has a summary and an array of { description, command, notes? }.

wd sandbox [info|run] [--allow-host <pattern>] [--no-network-filter] [--json]

Section titled “wd sandbox [info|run] [--allow-host <pattern>] [--no-network-filter] [--json]”

Detect or invoke an OS-level sandbox. See Sandbox.

Terminal window
wd sandbox info --json # what sandbox kind is available?
wd sandbox run -- wd apply --stage staging # run a command sandboxed
wd sandbox run --allow-host my-cdn.com -- wd deploy ... # extend the network allowlist
wd sandbox run --no-network-filter -- ... # disable proxy filtering

On macOS uses sandbox-exec (ships with the OS). On Linux uses bwrap (install via apt install bubblewrap). Windows returns WD_E_SANDBOX_BLOCKED.

Outbound HTTP(S) is funneled through a local proxy that enforces a hostname allowlist (Cloudflare, npm, GitHub, loopback by default). Use --allow-host (repeatable) to extend it; pass * or --no-network-filter to disable filtering entirely. Pattern syntax: .cloudflare.com matches any subdomain; exact strings match exactly.

Save and run reusable command sequences.

Terminal window
wd macro save smoke "wd check --stage staging && wd verify --stage staging"
wd macro save smoke "..." --dry-run --json # preview the save
wd macro list --json
wd macro run smoke
wd macro run smoke --dry-run --json # show what it would run
wd macro validate --json # check macros reference real commands

Macros are stored in .wrangler-deploy/macros.json.

The CLI accepts these flags everywhere. Several are also driven by environment variables for non-interactive / agent use.

FlagNotes
--json / --ndjsonMachine-readable output
--fields a,b.cProject JSON output to dot-paths
--output-file <path>Persist the first JSON payload to disk (any JSON-emitting command)
--quiet, -qSuppress non-error human output
--no-color (or NO_COLOR=1)Strip ANSI colour codes
FlagNotes
--input <path | ->Read JSON from a file or stdin (currently honoured by plan/apply/deploy)
Flag / envNotes
--dry-runPreview a write without performing it (every mutating command)
--sandbox (or AGENT_SANDBOX=1)Refuse mutating commands without --dry-run
--no-secrets-in-output (or WD_NO_SECRETS=1)Strip secret-shaped values from JSON output
--no-interactive (or WD_NO_INTERACTIVE=1)Refuse all prompts (auto-on under CI / non-TTY / sandbox)
--forceApply: re-run lifecycle even when state shows in-sync; destroy: bypass stage protection
FlagNotes
--stage <name>Required for stage-scoped commands; falls back to $WD_STAGE then $USER
--profile <name>Pick an auth profile (also reads WD_PROFILE/CLOUDFLARE_PROFILE)
--cwd <path>Run as if from a different project directory
--env-file <path>Load .env-style file before resolving env vars
--watchApply/deploy: re-run when config files change
Exit codeMeaning
0Success
1Runtime failure
2Validation or sandbox refusal
VariableEffect
AGENT_SANDBOX=1Refuse mutating commands without --dry-run. Auto-enables --no-interactive and --no-secrets-in-output.
WD_NO_INTERACTIVE=1Refuse all prompts.
WD_NO_SECRETS=1Strip secret-shaped values from JSON.
NO_COLOR=1Standard no-color signal.
CI=1 / CI=trueAuto-enables --no-interactive.
CLOUDFLARE_API_TOKENAPI token (required for requiresAuth commands).
CLOUDFLARE_ACCOUNT_IDAccount ID (required for requiresAuth commands).
WD_STAGEDefault stage when --stage is omitted.
WD_PROFILEDefault profile when --profile is omitted.
WD_STATE_PASSWORDPassword for encrypted state.

For the full agent surface (structured errors, NDJSON event streams, schemas) see the Agents section.

Generate shell completion scripts for tab-completion of commands and flags.

Terminal window
# Zsh
wd completions --shell zsh > ~/.zfunc/_wd
# Bash
wd completions --shell bash > /etc/bash_completion.d/wd
# Fish
wd completions --shell fish > ~/.config/fish/completions/wd.fish