· wrangler / cloudflare / workers

Wrangler 3 — the new Cloudflare Workers CLI reviewed

Upgrade from Wrangler 2. Local dev runs in the real workerd runtime, fidelity is higher, the feedback loop is faster. Budget an hour for the renames.

By

1,714 words · 9 min read

Upgrade from Wrangler 2. The v3 rewrite delivered one thing that actually matters: wrangler dev now runs your Worker locally in the real workerd runtime instead of simulating it in Node.js. The feedback loop is tighter and the fidelity is meaningfully higher. Wrangler 4 is now current stable (released March 2025), but v3 is where the platform shift happened — understanding it is prerequisite to using either.

Who this is for

Developers on Wrangler 2 deciding whether to upgrade, and developers evaluating Workers tooling for a new project. If you are starting fresh today, go directly to v4 — but read this to understand what changed and why the tooling is the way it is.

How we tested

Wrangler 3.x evaluated against version-pinned release notes, the official v2→v3 migration guide, and the workers-sdk GitHub changelog. No independent benchmarks were run. Cloudflare’s official sources make only qualitative performance claims for workerd versus Miniflare 2, and we will not substitute fabricated numbers.

The rewrite that mattered

Wrangler 3.0.0 shipped May 17, 2023. The headline change is not a command rename or a new flag — it is what runs your code during development.

In Wrangler 2, wrangler dev sent your Worker to Cloudflare’s network by default. Local mode existed but ran Miniflare 2: a custom JavaScript reimplementation of the Workers runtime, tens of thousands of lines trying to approximate platform behaviour in Node.js. Useful. Also a simulation, and simulations drift.

Wrangler 3 flipped the default and replaced the simulator. wrangler dev now runs locally by default, inside Miniflare 3, which embeds the actual open-source workerd runtime — the same C++ engine Cloudflare runs in production. You are not simulating Workers. You are running Workers.

The practical implication: CPU behaviour, compatibility flags, and the module execution model now match production by default. Storage bindings (KV, R2, D1) are still simulated locally when running offline, but the runtime itself is not. A class of “works locally, fails in production” bugs that Miniflare 2 could mask simply disappear.

Installation and the v2→v3 migration

Install or upgrade:

npm install -g wrangler@3

Check your version:

wrangler --version

The v2→v3 migration guide covers the full breaking-change list. The ones that will catch you:

wrangler publish is now wrangler deploy. Renamed at v3.0.0 for consistency with the dashboard. wrangler publish was kept as a deprecated alias throughout v3 and was fully removed in v4. If you have CI scripts hardcoding wrangler publish, update them now.

--local and --experimental-local are removed. In v2, local mode was opt-in via these flags. In v3, local is the default and the flags are gone. If your scripts passed --local, remove the flag. If they relied on remote-by-default behaviour for wrangler dev, add --remote explicitly.

Miniflare’s standalone CLI is gone. If you were running miniflare directly, switch to npx wrangler dev. The Miniflare GitHub repository was archived March 13, 2025 — no further standalone releases will ship.

That is the full list of sharp edges. The migration is not painful if you read the guide before starting.

Local dev: wrangler dev and --remote

# Runs your Worker locally in workerd — no Cloudflare account required for basic usage
wrangler dev

# Runs on Cloudflare's live network — uses your account credentials
wrangler dev --remote

The local-by-default model has two practical effects.

You can develop without a Cloudflare account. For Workers that do not require authenticated bindings, wrangler dev is completely offline. Faster iteration, no rate limits, no accidental requests to a production environment.

You get real runtime behaviour, not a polyfill. Compatibility flags, CPU limits, and the module execution model behave as they do on Cloudflare’s edge.

What local mode does not solve: service-level integration gaps. D1 local versus remote can surface schema differences. Durable Objects edge cases and Service bindings calling other Workers can behave differently under --remote. The rule of thumb: develop locally, gate with --remote before shipping anything that touches production state.

Deployment: wrangler deploy

wrangler deploy

No new ceremony. This is wrangler publish with a new name. The command authenticates, bundles your Worker with esbuild, and deploys it to Cloudflare’s network.

Pages integration arrived at v3.45.0. You can now use a wrangler config file for a Cloudflare Pages project, which unifies configuration between Workers and Pages Functions. Note that Workers-specific keys like main do not apply in Pages contexts — the config schemas overlap but are not identical. Read the Pages Functions wrangler config docs before porting a Workers config to a Pages project.

For a complete worked example deploying Workers with D1 and Stripe webhooks, see How to Deploy a Cloudflare Worker with D1 + Stripe.

New sub-commands

Wrangler 3 brought D1, R2, Queues, and more into first-class CLI tooling.

D1 — serverless SQL

[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "<your-database-id>"
wrangler d1 create my-database
wrangler d1 execute my-database --local --command "CREATE TABLE posts (id INTEGER PRIMARY KEY, title TEXT)"
wrangler d1 migrations apply my-database

For a 2026 production-readiness assessment of D1, see Cloudflare D1 in 2026: is it production-ready?.

R2 — object storage

[[r2_buckets]]
binding = "BUCKET"
bucket_name = "my-bucket"
wrangler r2 bucket create my-bucket
wrangler r2 object put my-bucket/key --file ./local-file.txt

v4 warning: in Wrangler 4, wrangler r2 commands default to local mode. Add --remote when targeting the production API. Automation scripts that relied on v3 behaviour will silently operate on local stores in v4 without it.

KV — key-value storage

[[kv_namespaces]]
binding = "KV"
id = "<your-namespace-id>"
wrangler kv namespace create MY_KV
wrangler kv key put --namespace-id=<id> foo bar

Syntax change at v3.60.0: the colon syntax (wrangler kv:namespace) is deprecated in favour of space syntax (wrangler kv namespace). The colon form will be removed in a future major version. If your scripts use it, update them — CI breakage from this change has been reported across multiple GitHub issues in the workers-sdk repo.

Same v4 warning as R2: data commands default to local in v4. Add --remote for production.

Queues

[[queues.producers]]
binding = "MY_QUEUE"
queue = "my-queue"

[[queues.consumers]]
queue = "my-queue"
max_batch_size = 10
wrangler queues create my-queue
wrangler queues list

Configuration format

Wrangler 3 supports three config formats: wrangler.toml (the v2 default), wrangler.json, and wrangler.jsonc. JSON and JSONC support arrived at v3.91.0. Cloudflare now recommends wrangler.jsonc for new projects.

Every config needs three mandatory fields regardless of format:

{
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2024-09-23"
}

The main field is optional only for assets-only Workers. The compatibility_date controls which platform API behaviours your Worker gets — set it to the date you last tested, not a future date.

One caveat: Cloudflare’s docs note that some newer features are exclusively available in JSON/JSONC config projects, but do not enumerate which ones. Verify this against the configuration reference when you need a specific feature.

DX pain points

Honest accounting of what does not work smoothly.

Module resolution edge cases. Wrangler bundles with esbuild. Packages that ship environment-specific conditional exports can trigger bundling errors locally that do not surface in a plain Node.js project. If your Worker imports a dependency and the bundle fails, check for conditional exports first before assuming a Wrangler bug.

Local/remote parity is not complete. The workerd runtime is high-fidelity for execution. Storage is not: D1 local versus remote can expose schema differences, and Durable Objects edge cases have surfaced in production after passing local tests. For anything stateful, validate with --remote before shipping.

The KV syntax change broke CI quietly. Scripts using kv:namespace colon syntax did not always throw an obvious error in early v3 minor versions — then the syntax stopped working. If you have scripts with wrangler kv:, grep and replace before upgrading.

Pages config confusion. Developers porting Workers configs to Pages projects regularly hit errors from unsupported keys. The schemas look similar but diverge on key fields, and the error messages are not always clear about which key is the problem.

Wrangler 4 — what changed

Wrangler 4.0.0 shipped March 13, 2025 and is now the current stable version. It is a much smaller major than v2→v3. The changes that matter for existing v3 users:

  • wrangler kv and wrangler r2 commands default to local mode in v4. Any automation targeting production must add --remote.
  • getBindingsProxy() is removed — use getPlatformProxy() instead.
  • wrangler publish is fully removed (deprecated alias since v3).
  • esbuild updated from 0.17 to 0.24 — check for bundling behaviour differences if you pin esbuild.

Check the v3→v4 migration guide for the complete list before upgrading. The Node.js minimum version floor for v4 was not confirmed at time of writing — verify this directly if you run a constrained Node environment.

Verdict

Migrate from v2 now. The local-by-default dev loop with workerd is a material improvement. The breaking changes — command renames, flag removals — are real but mechanical. Budget an hour, read the migration guide, and you are through.

Starting a new project? Go to v4 directly. Everything from v3 carried forward. The only reason to pin v3 is if a dependency has not caught up to v4’s esbuild version or API removals.

Running KV or R2 automation in CI? Add --remote before upgrading to v4. This is the one change that silently alters production behaviour without a runtime error — CI scripts that worked against production in v3 will silently operate on local stores in v4 without the flag.

The tooling now matches the platform it deploys to. That is worth the one-time migration cost.

If you are weighing Workers against other edge platforms, Cloudflare Workers vs Vercel Functions: 2026 Comparison covers the decision factors.

References