Skip to content

Accept wrangler.json(c) as a config - #8051

Merged
ry merged 12 commits into
mainfrom
ry/wrangler-json
Oct 28, 2026
Merged

ry merged 12 commits into
mainfrom
ry/wrangler-json

Conversation

@ry

@ry ry commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Lets workerd take a wrangler.json/wrangler.jsonc directly instead of a config.capnp. This is a developer-experience change: existing Workers projects run under workerd unchanged.

  • Supported fields: name, main, compatibility_date, compatibility_flags, vars, durable_objects.bindings, migrations (new, sqlite, renamed and deleted classes) and no_bundle. Any other field is rejected by deny_unknown_fields, so a config never silently half-works.
  • Bundling: shells out to esbuild with wrangler-like flags: ESM output, workerd conditions, node/cloudflare builtins external, and a require banner for CJS dependencies. If esbuild is missing, the error says how to fix it.
  • Defaults: listens on *:8787. DO storage goes in .wrangler/state/workerd, matching wrangler's layout.
  • --watch: reloads on the config file and on the inputs listed in esbuild's metafile. After a failed build it watches the project's sources, so fixing the error reloads.
  • Tests: unit tests cover JSONC, plain modules, DOs, migrations, unsupported fields and missing esbuild.

Does not support: KV, R2, D1, service bindings, define and rules.

`workerd serve wrangler.jsonc` translates a wrangler config into a
Config: name, main, compatibility_date/flags, vars, durable_objects
and migrations. main is bundled with esbuild the way wrangler does
it (WORKERD_ESBUILD, else node_modules/.bin/esbuild, else PATH), or
scanned as plain modules under "no_bundle". DO storage goes in
.wrangler/state/workerd. --watch reloads on changes to the config or
to any bundled input. Unsupported fields are an error.
@ry
ry requested review from a team as code owners October 27, 2026 23:14
@clanky-the-clanker

clanky-the-clanker Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

💬 Approved with comments — The earlier WARNING about the default bind address is fixed: it is now localhost:8787. Only two INFO notes remain, one about watch scope after a failed build and one about README defaults.

Findings: 2 info

Not opened by the correctness review: 6 changed files it was meant to read
  • samples/BUILD.bazel
  • samples/wrangler/.gitignore
  • samples/wrangler/src/index.ts
  • samples/wrangler/wrangler.jsonc
  • src/workerd/server/BUILD.bazel
  • src/workerd/server/cli/args.rs

The decision is advisory: this comment never approves, blocks or requests changes on the pull request.


⚡ Performance: 💬 1 info

One earlier INFO is still open: per-file watches after a failed build under --watch.

Recommendation: 💬 Optional Nits

  • [INFO] After a failed esbuild build under --watch, every source file under the project root gets its own watch, including files in dist/ and build/. A large project can hit the inotify limit. This affects only development. (src/workerd/server/cli/wrangler.rs:353)
View full review

src/workerd/server/cli/wrangler.rs:353-362: after a failed build, the code calls files(root) and watches every source file it returns. files() skips only node_modules and dot-directories, so it also walks output directories such as dist/ and build/.

Impact:

  • A large project can run out of inotify watches.
  • Writes into output directories can trigger reloads nobody asked for.
  • This affects only development with --watch, and only after a failed build.

Fix: skip common output directories, or watch directories instead of single files.


📝 Documentation: 💬 1 info

The README's wrangler section still does not give the listen address or the Durable Object state directory.

Recommendation: 💬 Optional Nits

  • [INFO] Give the defaults for a wrangler config in the README: the listen address (localhost:8787) and the Durable Object state directory (.wrangler/state/workerd/). (README.md:111)
View full review

README.md:111-115 introduces wrangler config support but does not say:

  • that the server listens on localhost:8787 by default;
  • that Durable Object state is stored under .wrangler/state/workerd/.

Adding both tells users where the server is reachable and where persistent state is written.


✅ All other checks passed

🔒 Security: ✅ LGTM

The previous WARNING is resolved:

  • DEFAULT_ADDRESS is now localhost:8787 (src/workerd/server/cli/wrangler.rs:32).
  • The module doc says the same and notes that --socket-addr overrides it.
  • A test asserts the address (wrangler-test.rs:99).

Checked and fine:

  • esbuild is spawned from an argument list, with no shell.
  • Bundles are written to .wrangler/tmp inside the project.
  • files() does not follow symlinks.
  • Unknown config fields are rejected.

📖 AGENTS.md: ✅ LGTM

The root AGENTS.md and src/workerd/server/AGENTS.md both say that wrangler.json(c) configs are accepted.


📋 Code Quality: ✅ LGTM

The only code changed since the last review is the default listen address, now localhost:8787 (src/workerd/server/cli/wrangler.rs:32). The module doc (wrangler.rs:17), wrangler-test.rs:99 and samples/wrangler/README.md all match it.


Reviewed commit: 976e5474

@ask-bonk

ask-bonk Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Since last review: 2 resolved, 0 still open, 0 new.
LGTM!


Reviewed commit: 976e5474 · github run

Comment thread src/workerd/server/cli/wrangler.rs Outdated
Comment thread src/workerd/server/cli/wrangler.rs
Comment thread src/workerd/server/cli/wrangler.rs Outdated
Comment thread src/workerd/server/cli/wrangler-test.rs Outdated
- Bundle into .wrangler/tmp in the project, not a predictable path in
  the shared temp dir.
- Key a Durable Object's storage by the name it was created under, so
  renamed_classes keeps its data.
- files() no longer follows symlinks, so a cycle cannot recurse.
- Test bundling, success and failure, against a stub esbuild.
- Mention wrangler configs in the README.
Comment thread src/workerd/server/cli/wrangler.rs
@codecov-commenter

codecov-commenter commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 2.04082% with 336 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.25%. Comparing base (47cde3f) to head (976e547).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
src/workerd/server/cli/wrangler.rs 1.21% 325 Missing ⚠️
src/workerd/server/cli/lib.rs 21.42% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8051      +/-   ##
==========================================
- Coverage   69.38%   69.25%   -0.13%     
==========================================
  Files         696      697       +1     
  Lines      181864   182210     +346     
  Branches    29213    29215       +2     
==========================================
+ Hits       126185   126191       +6     
- Misses      38612    38950     +338     
- Partials    17067    17069       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Within a migration, apply deleted_classes, then renamed_classes, then
new classes, as wrangler does, so a class can be deleted and re-created
in one migration. Reject deleting or renaming a class that does not
exist, and creating one that already does.
Comment thread src/workerd/server/cli/wrangler.rs Outdated
Comment thread src/workerd/server/cli/wrangler-test.rs
@ryanking13

Copy link
Copy Markdown
Contributor

I guess one thing we need to think about is that wrangler will be replaced by cf cli and it uses a .ts configuration file.

- Never reuse a Durable Object storage key: a class created under a
  name an earlier class was keyed by (deleted, or renamed away) gets
  <name>~<n> and starts empty, as in production. Previously a renamed
  class and a new class under its old name shared storage.
- Name the DO disk service after the worker, so a worker named
  wrangler-do-storage no longer collides with it.
- Watch main before bundling, so creating a missing main reloads.
- Serialize the tests that spawn processes, so the stub esbuild cannot
  fail with ETXTBSY.
- Test the DO binding, the uniqueKey a renamed class keeps, and that
  deletes apply before renames.
- List $schema among the README's supported fields.
Comment thread src/workerd/server/cli/wrangler-test.rs Outdated
@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

The generated output of @cloudflare/workers-types matches the snapshot in types/generated-snapshot 🎉

ry added 3 commits October 28, 2026 06:26
- Reject renaming a Durable Object class onto a name that exists.
- Test that bundling watches inputs only the metafile names.
- Module doc: name storage directories by key and list $schema; the
  root AGENTS.md mentions wrangler configs.
@ry

ry commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

@ryanking13 good point

I guess one thing we need to think about is that wrangler will be replaced by [cf cli (https://blog.cloudflare.com/cloudflare-cf-cli-launch/) and it uses a .ts configuration file.

This out of scope for this PR, as it would need Node.js execution - something workerd cannot provide now. That said, we shouldn't let that block DX improvements to workerd.

@jasnell jasnell left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but having at least one sample that uses wrangler.jsonc instead of the capnp would be helpful.

A TypeScript Worker with a SQLite-backed Durable Object, bundled with
esbuild. A unit test parses its config, so it cannot drift from what
the loader accepts.
Comment thread samples/wrangler/src/index.ts
@ry
ry enabled auto-merge (squash) October 28, 2026 21:12
A missing wrangler config was reported as a config error, so --watch
waited for it to change but never watched it. Report it as a usage
error, as for a missing .capnp config.
Comment thread src/workerd/server/cli/lib.rs
A wrangler config's server listened on every interface (*:8787).
wrangler dev listens on localhost; do the same, so a dev server is not
reachable from the network unless --socket-addr says so.
@ry
ry merged commit 82872d3 into main Oct 28, 2026
50 of 51 checks passed
@ry
ry deleted the ry/wrangler-json branch October 28, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants