Error [ERR_REQUIRE_ESM]: require() of ES Module not supported.
ID: node/err-require-esm
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 20 | active | — | — | — |
Root Cause
A CJS project is trying to require() a dependency that has migrated to ESM-only. Solutions: use dynamic import(), pin the last CJS version, or migrate the project to ESM.
genericWorkarounds
-
88% success Use dynamic import() with await in an async context
Replace const pkg = require('pkg') with const { default: pkg } = await import('pkg'). In CJS top-level code, wrap in async IIFE: (async () => { const pkg = await import('pkg'); })(); Note: import() returns a module namespace object. -
92% success Pin the last CJS version of the dependency
Check the dependency's changelog for the last version before ESM migration. Common examples: chalk@4, got@11, node-fetch@2, ora@5, execa@5, globby@11, p-limit@3. Pin with: npm install pkg@version --save-exact.
-
85% success Migrate the entire project to ESM
Set type: module in package.json. Replace all require() with import. Replace __dirname with import.meta.dirname (Node 21.2+) or fileURLToPath(import.meta.url). Replace module.exports with export default. Update jest/test config for ESM.
Sources: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
Dead Ends
Common approaches that don't work:
-
Adding type: module to package.json without updating require() calls
85% fail
Setting type: module makes ALL .js files in the project ESM. Every require() call breaks with 'require is not defined in ES module scope'. This requires a full codebase migration, not a one-line config change.
-
Using dynamic import() synchronously in CJS code
88% fail
import() returns a Promise and is always asynchronous. It cannot be used as a drop-in replacement for synchronous require(). Code that depends on the module being available synchronously must be restructured to use async/await.
-
Transpiling the ESM dependency back to CJS with babel
72% fail
Transpiling node_modules is fragile, slow, and may break the dependency's internal ESM imports. Most bundlers exclude node_modules by default for good reason.