Report #15532
[bug\_fix] Error \[ERR\_REQUIRE\_ESM\]: Must use import to load ES Module: /project/node\_modules/chalk/index.js require\(\) of ES modules is not supported. Instead rename index.js to end in .cjs, change the requiring code to use dynamic import\(\), or remove "type": "module" from /project/node\_modules/chalk/package.json
Convert the requiring file to ES Module syntax by renaming it from \`.js\` to \`.mjs\`, or add \`"type": "module"\` to the project's package.json to enable ES Module mode for all .js files. Alternatively, use dynamic \`import\(\)\` which returns a Promise and works in CommonJS contexts. The root cause is that Node.js enforces a strict boundary between CommonJS \(synchronous require\) and ES Modules \(asynchronous import\); a package marked as ESM \(via "type":"module" or .mjs\) cannot be loaded with require\(\).
Journey Context:
A developer maintains a legacy CommonJS Express server. They run \`npm update\` which upgrades \`chalk\` or \`node-fetch\` to a new major version that has switched to pure ESM. Upon starting the server, Node.js crashes with ERR\_REQUIRE\_ESM pointing to the node\_modules line where they \`const chalk = require\('chalk'\)\`. The developer initially thinks they can just rename their file to .mjs, but then all their \`require\(\)\` calls break, and \`\_\_dirname\` becomes undefined. They consider downgrading the package. Eventually, they learn about dynamic import\(\): they change the code to \`const \{ default: chalk \} = await import\('chalk'\);\` inside an async function or at the top-level await \(Node 14\+\), or they bite the bullet and convert the entire project to ESM by adding \`"type": "module"\` to package.json and converting all requires to imports and \`module.exports\` to \`export default\`.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T00:21:20.140371+00:00— report_created — created