---
title: "How we rebuilt Cloudflare Workers’ module registry for Node.js compatibility"
description: "Cloudflare has rebuilt the module registry in workerd, the open-source core of the Workers runtime, to improve speed, standards compliance, and alignment with Node.js. The change addresses compatibility beyond runtime APIs by making module resolution, loading, and caching behave more like Node.js across ESM, CommonJS, and WebAssembly. The new registry uses URLs as specifiers, supports import.meta.url, import.meta.main, and import.meta.resolve(), distinguishes modules by query strings and fragments, validates import attributes, follows require(esm) rules, and compiles modules lazily while sharing caches across isolates. It also supports WebAssembly source phase imports and consistent loading errors; the existing registry remains in place, and the new implementation must be enabled with the new_module_registry compatibility flag."
---

# How we rebuilt Cloudflare Workers’ module registry for Node.js compatibility

[Cloudflare](https://yomu.fyi/company/cloudflare) · Logan Gatlin · Sep 9, 2026

**Type:** Explainer

## Summary

Cloudflare has rebuilt the module registry in workerd, the open-source core of the Workers runtime, to improve speed, standards compliance, and alignment with Node.js. The change addresses compatibility beyond runtime APIs by making module resolution, loading, and caching behave more like Node.js across ESM, CommonJS, and WebAssembly. The new registry uses URLs as specifiers, supports import.meta.url, import.meta.main, and import.meta.resolve(), distinguishes modules by query strings and fragments, validates import attributes, follows require(esm) rules, and compiles modules lazily while sharing caches across isolates. It also supports WebAssembly source phase imports and consistent loading errors; the existing registry remains in place, and the new implementation must be enabled with the new\_module\_registry compatibility flag.

## Context

Workers needed compatibility with Node.js applications beyond individual runtime APIs. Module resolution, loading, and caching behavior also affects applications, while the original registry used filesystem-style paths, compiled the entire bundle up front, and kept separate copies per V8 isolate.

## Approach / What changed

The new workerd registry uses URLs as module specifiers and builds in lazy compilation and cache sharing. It adds Node.js-aligned behavior for import.meta APIs, URL-based resolution, module identity, import attributes, require(esm), error handling, and WebAssembly source phase imports. Workers can opt in with the new\_module\_registry compatibility flag.

## Takeaways

- Module specifiers are parsed as URLs, so relative imports follow new URL() resolution rules; query strings and fragments create distinct module instances.
- The registry compiles modules when first imported, whether statically or dynamically, rather than compiling the entire Worker bundle up front.
- WebAssembly source phase imports return a WebAssembly.Module directly, but source phase imports for other module types currently throw a SyntaxError.

**Tags:** [JavaScript](https://yomu.fyi/topic/javascript), [Node.js](https://yomu.fyi/topic/node-js), [Open Source](https://yomu.fyi/topic/open-source)

- Source: [Cloudflare](https://blog.cloudflare.com/workers-module-registry-nodejs)
- Source URL: https://blog.cloudflare.com/workers-module-registry-nodejs
- Ingested by Yomu: 2026-09-09T16:00:58.382Z

[Read original post](https://blog.cloudflare.com/workers-module-registry-nodejs)
