From 6afbeff879ae41d89740725906018e29169d0c27 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Sat, 17 Oct 2026 08:25:46 -0700 Subject: [PATCH 1/2] [Workers] Announce new module registry default on November 1 --- .../2026-10-17-module-registry-default.mdx | 47 +++++++++++++++++++ .../new-module-registry.md | 22 +++++++++ .../docs/workers/wrangler/bundling.mdx | 6 +++ 3 files changed, 75 insertions(+) create mode 100644 src/content/changelog/workers/2026-10-17-module-registry-default.mdx create mode 100644 src/content/compatibility-flags/new-module-registry.md diff --git a/src/content/changelog/workers/2026-10-17-module-registry-default.mdx b/src/content/changelog/workers/2026-10-17-module-registry-default.mdx new file mode 100644 index 00000000000..b3cd78b5348 --- /dev/null +++ b/src/content/changelog/workers/2026-10-17-module-registry-default.mdx @@ -0,0 +1,47 @@ +--- +title: The new Workers module registry will be the default on November 1 +description: JavaScript Workers with compatibility dates on or after November 1, 2026 will use URL-based module resolution and import.meta by default. +products: + - workers +date: 2026-10-17 +--- + +import { TypeScriptExample, WranglerConfig } from "~/components"; + +Starting November 1, 2026, JavaScript Workers with a [compatibility date](/workers/configuration/compatibility-dates/) of `2026-11-01` or later will use the new module registry by default. You will no longer need the `new_module_registry` flag for these dates. Python Workers keep using the legacy registry. + +We [announced the registry rewrite in September 2026](https://blog.cloudflare.com/workers-module-registry-nodejs/). It improves compatibility with JavaScript standards and Node.js module loading, including URL-based resolution, validated import attributes, and `require(esm)` behavior. + +You can use `import.meta` to inspect the current module and resolve relative specifiers without loading another module: + + + +```ts +export default { + fetch(): Response { + return Response.json({ + moduleUrl: import.meta.url, + isEntrypoint: import.meta.main, + helperUrl: import.meta.resolve("./helper.js"), + }); + }, +} satisfies ExportedHandler; +``` + + + +When deployed with `src/index.ts` as the unbundled entrypoint, `isEntrypoint` is `true`. `helperUrl` resolves to a URL within your Worker bundle; resolution does not check whether that module exists or load it over the network. Build tools may transform `import.meta`, so use an [unbundled deployment](/workers/wrangler/configuration/#bundling) to try this example directly. + +Your Worker keeps its current behavior until you update its compatibility date or explicitly opt in. To test before November 1, keep your existing date and add the flag: + + + +```toml +compatibility_flags = ["new_module_registry"] +``` + + + +Before updating, check dependencies that rely on ignored import attributes or legacy `require()` behavior. The new registry rejects invalid import attributes and `require()` of module graphs containing top-level `await`. To keep the legacy registry with a compatibility date of `2026-11-01` or later, use `legacy_module_registry`. + +For migration details, refer to the [new module registry compatibility flag](/workers/configuration/compatibility-flags/#new-module-registry), [bundling documentation](/workers/wrangler/bundling/#runtime-module-loading), and [Node.js compatibility documentation](/workers/runtime-apis/nodejs/). diff --git a/src/content/compatibility-flags/new-module-registry.md b/src/content/compatibility-flags/new-module-registry.md new file mode 100644 index 00000000000..0304b79af66 --- /dev/null +++ b/src/content/compatibility-flags/new-module-registry.md @@ -0,0 +1,22 @@ +--- +name: "New module registry" +sort_date: "2026-11-01" +enable_date: "2026-11-01" +enable_flag: "new_module_registry" +disable_flag: "legacy_module_registry" +--- + +For compatibility dates on or after November 1, 2026, JavaScript Workers use the new module registry by default. For earlier dates, add `new_module_registry` to opt in. Add `legacy_module_registry` to retain the legacy registry with a later compatibility date. Python Workers continue to use the legacy registry. + +The registry resolves and loads the modules uploaded with your Worker and the runtime's built-in modules. It provides `import.meta.url`, `import.meta.main`, and `import.meta.resolve()`, and resolves module specifiers as URLs. Different query strings or fragments create separate module instances, even when they refer to the same source. + +Review these differences before changing your compatibility date: + +- Import attributes are validated. Unknown attribute keys, unsupported types, and types that do not match the imported module throw errors. +- `require()` of an ES module returns its namespace unless it exports a value named `"module.exports"`. Workers' built-in `node:` modules return their default export. The `__cjsUnwrapDefault` marker in existing bundles still unwraps the default export. +- `require()` rejects module graphs containing top-level `await`, even if the graph has already finished evaluating. Use dynamic `import()` for these modules. +- The legacy-registry flags `export_commonjs_default`, `require_returns_default_export`, `throw_on_unrecognized_import_assertion`, and `disable_top_level_await_in_require` do not control the new registry. + +The registry does not download modules from arbitrary URLs or install npm dependencies. Your build tooling still determines which modules are uploaded and may transform imports or `import.meta` before deployment. Refer to [Bundling](/workers/wrangler/bundling/#runtime-module-loading) and [Node.js compatibility](/workers/runtime-apis/nodejs/). + +For background and examples, refer to [How we rebuilt Cloudflare Workers' module registry for Node.js compatibility](https://blog.cloudflare.com/workers-module-registry-nodejs/). diff --git a/src/content/docs/workers/wrangler/bundling.mdx b/src/content/docs/workers/wrangler/bundling.mdx index 47e554d7f4a..e0925284e73 100644 --- a/src/content/docs/workers/wrangler/bundling.mdx +++ b/src/content/docs/workers/wrangler/bundling.mdx @@ -25,6 +25,12 @@ You can provide `rules` and set `find_additional_modules` in your configuration Furthermore, we have an escape hatch in the form of [Custom Builds](/workers/wrangler/custom-builds/), which lets you run your own build before Wrangler's built-in one. ::: +## Runtime module loading + +The runtime's module registry resolves and loads the modules that your build uploads. For compatibility dates on or after November 1, 2026, JavaScript Workers use the [new module registry](/workers/configuration/compatibility-flags/#new-module-registry) by default. With earlier dates, add `new_module_registry` to opt in. Use `legacy_module_registry` to opt out with a later date. + +The new registry supports `import.meta.url`, `import.meta.main`, and `import.meta.resolve()`, URL-based module resolution, and validated import attributes. Your bundler may transform these expressions before the runtime receives your code. To preserve your module graph, use [unbundled deployments](/workers/wrangler/configuration/#bundling) or configure [additional modules](#find-additional-modules). + ## Including non-JavaScript modules {/* Changes to this section should also be applied to /workers/vite-plugin/reference/non-javascript-modules */} From 8acf71131c0ee62ee15f54708b1d3f334986a876 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Sat, 17 Oct 2026 09:06:46 -0700 Subject: [PATCH 2/2] [Workers] Add cf guidance to module registry changelog --- .../2026-10-17-module-registry-default.mdx | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/content/changelog/workers/2026-10-17-module-registry-default.mdx b/src/content/changelog/workers/2026-10-17-module-registry-default.mdx index b3cd78b5348..14b2b3f1dd9 100644 --- a/src/content/changelog/workers/2026-10-17-module-registry-default.mdx +++ b/src/content/changelog/workers/2026-10-17-module-registry-default.mdx @@ -1,5 +1,5 @@ --- -title: The new Workers module registry will be the default on November 1 +title: Workers will use the new module registry by default on November 1 description: JavaScript Workers with compatibility dates on or after November 1, 2026 will use URL-based module resolution and import.meta by default. products: - workers @@ -10,9 +10,9 @@ import { TypeScriptExample, WranglerConfig } from "~/components"; Starting November 1, 2026, JavaScript Workers with a [compatibility date](/workers/configuration/compatibility-dates/) of `2026-11-01` or later will use the new module registry by default. You will no longer need the `new_module_registry` flag for these dates. Python Workers keep using the legacy registry. -We [announced the registry rewrite in September 2026](https://blog.cloudflare.com/workers-module-registry-nodejs/). It improves compatibility with JavaScript standards and Node.js module loading, including URL-based resolution, validated import attributes, and `require(esm)` behavior. +The module registry finds and loads JavaScript modules in your Worker. We [announced the new registry in September 2026](https://blog.cloudflare.com/workers-module-registry-nodejs/). It improves compatibility with JavaScript standards and Node.js. In Workers using [Node.js compatibility](/workers/runtime-apis/nodejs/), you can use `require()` to load ES modules. The module and its dependencies must not use top-level `await`. -You can use `import.meta` to inspect the current module and resolve relative specifiers without loading another module: +You can also use `import.meta` to get information about the current module and find the URL of another module without loading it: @@ -30,11 +30,22 @@ export default { -When deployed with `src/index.ts` as the unbundled entrypoint, `isEntrypoint` is `true`. `helperUrl` resolves to a URL within your Worker bundle; resolution does not check whether that module exists or load it over the network. Build tools may transform `import.meta`, so use an [unbundled deployment](/workers/wrangler/configuration/#bundling) to try this example directly. +When deployed with `src/index.ts` as the unbundled entrypoint, `isEntrypoint` is `true`. `helperUrl` is a URL within your Worker bundle. Resolving the URL does not check whether the module exists or load it over the network. Build tools may transform `import.meta`. To try this example directly, refer to [build settings for cf](/cf/wrangler/reference/#build-settings) or [unbundled deployments with Wrangler](/workers/wrangler/configuration/#bundling). -Your Worker keeps its current behavior until you update its compatibility date or explicitly opt in. To test before November 1, keep your existing date and add the flag: +Existing Workers keep their current behavior until you change their compatibility date or flags. To try the new registry before November 1, keep your current date and add `new_module_registry` to your existing flags. With [`cf`](/cf/get-started/), set `worker.compatibilityFlags` in [`cloudflare.config.ts`](/cf/projects/cloudflare-config/). With Wrangler, set `compatibility_flags`: - + ```toml compatibility_flags = ["new_module_registry"] @@ -42,6 +53,8 @@ compatibility_flags = ["new_module_registry"] -Before updating, check dependencies that rely on ignored import attributes or legacy `require()` behavior. The new registry rejects invalid import attributes and `require()` of module graphs containing top-level `await`. To keep the legacy registry with a compatibility date of `2026-11-01` or later, use `legacy_module_registry`. +With `cf`, run `cf dev` to test locally, then `cf deploy` to publish the change. For an existing Wrangler project, follow the [migration guide](/cf/wrangler/migrate/) before switching to `cf`. + +Before updating, check your dependencies for invalid import attributes and changes to `require()` behavior. The new registry rejects invalid import attributes. Calls to `require()` also fail if the module or any of its dependencies use top-level `await`. To keep the legacy registry with a compatibility date of `2026-11-01` or later, add `legacy_module_registry` to the same flags list instead of `new_module_registry`. For migration details, refer to the [new module registry compatibility flag](/workers/configuration/compatibility-flags/#new-module-registry), [bundling documentation](/workers/wrangler/bundling/#runtime-module-loading), and [Node.js compatibility documentation](/workers/runtime-apis/nodejs/).