Skip to content

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.

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.jsonc as 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 Env from 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

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.jsonc stays readable and dev-friendly.
  • wrangler-deploy renders stage-specific wrangler.rendered.jsonc files when it needs real IDs and stage-suffixed names.
  • wrangler dev still uses the files you already have.
  • wd dev can either spawn one Wrangler process per worker or one shared Queue-oriented local session.
  • wd deploy uses 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
Terminal window
wd init # scan existing wrangler.jsonc files
wd plan # dry-run, show what would change
wd apply # provision resources
wd deploy # deploy workers in dependency order
wd verify # post-deploy health checks
wd destroy # reverse-order teardown

The important split is simple:

  • Dev keeps using your existing wrangler.jsonc.
  • Deploy uses rendered wrangler.rendered.jsonc with 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.

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.

  • Additive: Wrangler still handles auth, deploy, and local dev. wrangler-deploy sits on top.
  • JSONC-first: Your existing wrangler.jsonc files stay in place. No rewrite step. No migration away from Wrangler.
  • Built for both dev and deploy: Keep using wrangler dev, use wd dev for multi-worker local startup, or use wd dev --session when you want a shared Queue local-dev session.
  • Type-safe: Worker Env types 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.