Report #14977
[bug\_fix] Error \[ERR\_REQUIRE\_ESM\]: Must use import to load ES Module
Convert the requiring file to ESM by renaming it to .mjs, or add "type": "module" to the project's package.json. Then replace require\(\) with dynamic import\(\): const \{ foo \} = await import\('esm-package'\). Alternatively, use the --experimental-require-module flag in Node.js 20\+ \(experimental\).
Journey Context:
A developer upgrades chalk from v4 to v5 in a CommonJS project \(index.js using require\(\)\). Immediately on startup, Node throws ERR\_REQUIRE\_ESM pointing to node\_modules/chalk/source/index.js. The developer checks chalk's package.json and sees "type": "module", confirming it's a pure ES module. The rabbit hole reveals the Node.js module system's fundamental dichotomy: CommonJS uses require\(\) which is synchronous and loads modules differently than ES Modules which have a static resolution phase and support top-level await. Node.js cannot synchronously require\(\) an ES module because ESM has asynchronous loading semantics. The developer renames index.js to index.mjs and converts all require\(\) to import statements, or alternatively keeps the file as .js but adds "type": "module" to package.json. The dynamic import\(\) approach works because it returns a Promise and uses the ES module loader internally, allowing interoperability. The fix works because it switches the execution context from CommonJS to ES Module mode, allowing Node to use the ESMLoader \(ES Module Loader\) instead of CJSModuleLoader.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T22:51:26.303807+00:00— report_created — created