Cloudflare rewrote the module registry inside workerd so that specifiers resolve with URL semantics instead of as filesystem paths. That single change is what finally brings import.meta, spec-compliant import attributes, require(esm) and WebAssembly source phase imports to Workers — and it arrives behind an opt-in compatibility flag with no default-on date, which makes enabling it a decision rather than an upgrade.
What changed
Workers runs on workerd, and until now workerd's module registry resolved specifiers as filesystem-style paths, not URLs. That is the root of everything downstream. A path-based resolver has nowhere to put a query string, no notion of a URL origin, and no way to tell ./mod.js?v=1 apart from ./mod.js. The rewrite resolves every specifier with new URL() semantics instead.
What that unlocks, per Cloudflare's write-up:
-
import.metais fully supported, includingimport.meta.url,import.meta.mainandimport.meta.resolve(). - Query strings and fragments now produce distinct module instances, so two imports of the same file with different query strings are two modules.
-
node:protocol specifiers consistently resolve to the same module instance rather than a fresh copy per import site. - Import attributes are validated against the specification. JSON imports are checked, and unsupported types such as
textandbytesraise specific errors instead of failing silently. -
require(esm)follows Node.js' own ECMAScript module loading rules. - WebAssembly source phase imports work, giving direct access to a compiled but uninstantiated WASM module.
- Static
import, dynamicimport()andrequire()return the same error classes with the same messages.
Two performance properties are designed into the new registry rather than bolted on afterwards. Modules compile lazily — at first import, not upfront — so a Worker that imports a large dependency on a cold path does not pay for it on every start. And code caches are shared across V8 isolate replicas, which means identical source is compiled once instead of once per parallel replica.
Activation is a compatibility flag in wrangler.json:
{
"compatibility_flags": ["new_module_registry"]
}
Cloudflare is explicit about what that flag does not do: "It doesn't have a default on date yet, so it won't turn on automatically."
Who this affects
Workers projects that pull in npm packages written for Node.js are the ones this was built for. Any codebase that has a shim standing in for import.meta.url, that avoids require() of an ES module because the failure mode was unclear, or that keeps a dependency out because its import attributes did not validate, now has a supported path instead of a workaround.
Workers that import WASM gain the most concrete new capability: source phase imports hand over a compiled but uninstantiated module, which is the shape needed to control instantiation timing or to instantiate the same module more than once.
This does not matter to a Worker that imports a handful of local ES modules and nothing else. Path-style resolution already handled that case, and enabling the flag buys such a project nothing but a behavioural delta to re-test. The same goes for anyone whose deployment pipeline treats compatibility flags as frozen configuration — the flag is opt-in precisely because the semantics change.
Verdict
Enable it in a preview environment now; do not flip it on a production Worker this week. The semantics genuinely change — query strings and fragments create separate module instances, and import attributes that previously passed through can now throw — so a Worker with a non-trivial dependency tree needs a real test pass, not a smoke test.
The absence of a default-on date is the useful signal here. Cloudflare is not forcing a migration deadline, which means there is no penalty for waiting and no reward for rushing. The right move is to enable the flag on a branch, run the existing test suite against it, and note whatever breaks. That work has to happen eventually, and doing it while the old registry is still the default is strictly cheaper than doing it under a deadline.
Projects blocked today on import.meta or WASM source phase imports are the exception: for them the flag is the fix, and waiting has a cost the others do not pay.
Tracked daily from official release feeds and vendor changelogs. Full archive: https://media.patentllm.org
Top comments (0)