Introduction
wrangler-deploy sits on top of wrangler. It is a deploy tool, but it is also a development tool for projects that already live in wrangler.jsonc. You keep your existing config files, keep using wrangler dev, and add one file at the repo root: wrangler-deploy.config.ts.
This is intentionally not a pitch to move away from wrangler.jsonc. wrangler.jsonc works fine. The goal is to keep it and add the missing repo-level workflows around it.
wrangler.jsonc stays the authoring surface for local development. wrangler-deploy reads it, renders stage-specific configs only when needed, and leaves your checked-in worker configs in place.
That extra file tells wrangler-deploy what resources exist, which workers use them, and how stages should behave. From there it can create stage-specific resources, render stage-specific wrangler.jsonc files with the right IDs, deploy in the right order, and tear everything down when the stage is done.
Wrangler still provides the underlying primitives. The value here is that wrangler-deploy turns those primitives into repo-aware workflows. Instead of remembering which worker owns a Queue binding, which local port it landed on, or which ad hoc route to hit in development, you use logical names from one project config and let the tool resolve the rest.
That same config also gives you typed Worker Env objects through workerEnv(...) and typeof api.Env. The type is inferred from the bindings you declare, so you get compile-time safety without code generation or a runtime helper library just to produce the type.
The problem
Section titled “The problem”Cloudflare Workers projects usually start with wrangler.jsonc, then grow into something messier. A second worker gets added. Then a queue. Then D1. Then a preview environment. At that point the hard part is not writing the worker code. It is keeping IDs, bindings, deploy order, and cleanup steps straight across environments.
wrangler.jsonc is still the right source for local development. The problem is not that wrangler.jsonc is wrong. The problem is that raw Wrangler does not give you a good way to treat a whole multi-worker app as one stageable system.
flowchart LR
subgraph "Without wrangler-deploy"
A["Create D1 in dashboard"] --> B["Copy ID to wrangler.jsonc"]
C["Create KV in dashboard"] --> D["Copy ID to wrangler.jsonc"]
E["Create Queue in CLI"] --> F["Copy ID to wrangler.jsonc"]
B --> G["wrangler deploy"]
D --> G
F --> G
end
There is no standard way to:
- Provision all resources for a new stage in one command
- Keep
wrangler.jsoncas the source of truth for dev, while generating deployable configs per stage - Deploy workers in dependency order
- Tear down a stage cleanly
- Get typed Worker
Envfrom a single config
There is also no good repo-level answer to local runtime workflows once the app gets bigger. Raw Wrangler can start processes and expose local routes, but it still leaves the user to figure out:
- which worker to call
- which port it is on right now
- which worker produces to a queue and which one consumes it
- how to replay a cron or queue flow without hand-written shell scripts
The solution
Section titled “The solution”You add wrangler-deploy.config.ts next to your existing wrangler.jsonc files. That file does not replace Wrangler config. It complements it.
- Your checked-in
wrangler.jsoncstays readable and dev-friendly. - wrangler-deploy renders stage-specific
wrangler.rendered.jsoncfiles when it needs real IDs and stage-suffixed names. wrangler devstill uses the files you already have.wd devcan either spawn one Wrangler process per worker or one shared Queue-oriented local session.wd deployuses the rendered files built for that stage.
If you are happy with wrangler.jsonc today, the intended outcome is that you still are.
flowchart LR
subgraph "With wrangler-deploy"
A["wrangler-deploy.config.ts"] --> B["wd apply"]
B --> C["Resources created\nIDs captured in state"]
C --> D["wd deploy"]
D --> E["Workers deployed\nwith correct bindings"]
E --> F["wd destroy"]
F --> G["Everything cleaned up"]
end
Commands
Section titled “Commands”wd init # scan existing wrangler.jsonc fileswd plan # dry-run, show what would changewd apply # provision resourceswd deploy # deploy workers in dependency orderwd verify # post-deploy health checkswd destroy # reverse-order teardownThe important split is simple:
- Dev keeps using your existing
wrangler.jsonc. - Deploy uses rendered
wrangler.rendered.jsoncwith real IDs for that stage.
The other important split is:
- Wrangler gives you low-level commands per worker.
- wrangler-deploy gives you app-level commands across the whole repo.
That is why commands like wd dev doctor, wd cron trigger, and wd queue send matter. They are not replacing Wrangler’s runtime. They are removing the need to remember which worker, which port, and which local convention applies in a given repo.
It is also why the config exports a phantom Env type for each worker. You write the bindings once, then import the inferred type where you use it.
That is why JSONC stays first-class instead of turning into something you have to work around.
How stages work
Section titled “How stages work”A stage is an isolated copy of your stack: resources, workers, bindings, and state. Give it a name like pr-42, staging, or production and wrangler-deploy keeps that environment separate from the rest.
flowchart TD
Config["wrangler-deploy.config.ts"]
Config --> Staging["Stage: staging"]
Config --> PR["Stage: pr-42"]
Config --> Prod["Stage: production"]
Staging --> S_D1["payments-db-staging"]
Staging --> S_KV["cache-kv-staging"]
Staging --> S_Worker["payment-api-staging"]
PR --> P_D1["payments-db-pr-42"]
PR --> P_KV["cache-kv-pr-42"]
PR --> P_Worker["payment-api-pr-42"]
Prod --> R_D1["payments-db-production"]
Prod --> R_KV["cache-kv-production"]
Prod --> R_Worker["payment-api-production"]
That gives you something Wrangler alone does not really give you out of the box: a repeatable full-environment workflow. A PR can get its own D1, KV, queues, worker names, service bindings, and cleanup path without touching staging or production.
Key principles
Section titled “Key principles”- Additive: Wrangler still handles auth, deploy, and local dev. wrangler-deploy sits on top.
- JSONC-first: Your existing
wrangler.jsoncfiles stay in place. No rewrite step. No migration away from Wrangler. - Built for both dev and deploy: Keep using
wrangler dev, usewd devfor multi-worker local startup, or usewd dev --sessionwhen you want a shared Queue local-dev session. - Type-safe: Worker
Envtypes come from config. No generated files to commit. - Safe by default: Protected stages, resumable apply, dependency-aware deploy and destroy order.
- Usable in teams: Put state in KV and let local dev, CI, and teammates operate on the same stage without guessing.