What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Node.js 23 brought several developer-experience changes into focus: CommonJS could synchronously load some ES modules, node --run became stable, and the built-in test runner gained glob patterns for coverage files. The headline feature had an important boundary: in Node 23.0.0, require(esm) was experimental and could not load an ESM graph containing top-level await.

What changed in Node.js 23?

Bytes issue 341, published November 14, 2024, highlighted Node.js 23 as a response to developer-facing capabilities associated with newer JavaScript runtimes. The practical story is interoperability and tooling—not a wholesale replacement of Node’s module system or a claim that every highlighted feature was unique to Node 23.

Node.js 23.0.0 was released on October 16, 2024. Its release announcement called out three changes: require(esm) enabled by default, stable node --run, and glob pattern support for test coverage files. The release also described the state of each feature, which matters when deciding whether to rely on it. Node.js 23.0.0 release announcement.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can CommonJS require an ES module in Node.js 23?

Yes, with a compatibility condition. In Node 23.0.0, CommonJS code could use require() to load a native ES module graph when that graph could execute synchronously. The returned value is an ES module namespace object. The capability was enabled by default, but the Node.js project still classified it as experimental in that release.

The key limitation is top-level await. If the requested module or a dependency in its graph uses top-level await, the graph is asynchronous and require() can fail with ERR_REQUIRE_ASYNC_MODULE. Use import when the module graph needs asynchronous evaluation rather than assuming CommonJS loading will work.

For code that needs to detect support, the release notes describe checking process.features.require_module. They also document the "module-sync" exports condition, which package authors can use to direct compatible require() and import consumers to a synchronous module entry point. Node’s announcement cautioned: “This feature is still experimental, and we are looking for user feedback to make more final tweaks before fully stabilizing it.”

Was require(esm) exclusive to Node 23?

No. Node.js 22.12.0, released November 21, 2024, also enabled require(esm) by default. The capability was therefore available by default in both the Node 23.0.0 release and the later Node 22.12.0 release; it was not a feature exclusive to the Node 23 line. The same synchronous-graph constraint remains central to understanding what the behavior means. Node.js 22.12.0 release announcement.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What does node --run do?

Node 23.0.0 marked node --run stable. It runs scripts declared in a project’s package.json using the Node executable, offering a built-in way to invoke project scripts. This is script execution, not a replacement for a package manager’s dependency installation or other package-management functions. See the Node.js 23.0.0 announcement for the release details.

What changed in test coverage?

Node 23.0.0 added glob pattern support for coverage files in the built-in test runner. Patterns make it easier to match coverage across multiple files. This change concerns which files are matched for coverage; it should not be read as a general change to every test-selection or test-runner behavior.

Can Node.js 23 run TypeScript files without a build step?

Node 23.6.0 enabled --experimental-strip-types by default, allowing Node to execute .ts files directly when they use syntax within the supported subset. The release, published January 7, 2025, emphasized that this feature remained experimental and had documented limitations. Node.js 23.6.0 release announcement.

Type stripping removes supported type syntax so JavaScript can run; it is not full TypeScript compilation and does not type-check a program. A project that relies on syntax or transformations outside Node’s supported subset still needs an appropriate build or transpilation workflow. Running a TypeScript file directly should not be mistaken for validating its types.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How to interpret the Bytes #341 headline

“Node strikes back” captures the issue’s emphasis on Node catching up with developer conveniences, especially loading synchronous ESM from CommonJS. The more precise takeaway is versioned: Node 23.0.0 enabled that experimental interoperability path, Node 22.12.0 later enabled it as well, and Node 23.6.0 made limited experimental type stripping default-on. These changes improved flexibility without eliminating module-graph constraints or turning Node into a full TypeScript compiler.

Bytes #341 — Node strikes back was published November 14, 2024.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.