Skip to content
JS
Node.js error

ERR_REQUIRE_ESM

CommonJS code called require() on a file that Node.js treats as an ES module, and the running Node.js version (or a flag) does not allow require() to load ES modules. The file is usually a dependency that became ESM-only in a major release.

Updated Node.js
Error [ERR_REQUIRE_ESM]: require() of ES Module /app/lib/util.js from /app/index.js not supported.
util.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead either rename util.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in /app/lib/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).
Node.js 16.6.0 and later (.js file without ES module syntax in a "type": "module" package). Node.js 16.x prints "Instead rename" without "either".
Error [ERR_REQUIRE_ESM]: require() of ES Module /app/lib/util.mjs not supported.
Instead change the require of /app/lib/util.mjs to a dynamic import() which is available in all CommonJS modules.
Node.js 16.6.0 and later (.mjs file)
Error [ERR_REQUIRE_ESM]: require() of ES Module /app/node_modules/node-fetch/src/index.js from /app/server.js not supported.
Instead change the require of index.js in /app/server.js to a dynamic import() which is available in all CommonJS modules.
Node.js 16.6.0 and later (.js file with ES module syntax in a "type": "module" package)
Earlier wording (2)
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /app/node_modules/node-fetch/src/index.js
require() of ES modules is not supported.
require() of /app/node_modules/node-fetch/src/index.js from /app/server.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /app/node_modules/node-fetch/package.json.
Node.js 12 to 16.5 (.js file in a "type": "module" package)
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /app/lib/util.mjs
Node.js 12 to 16.5 (.mjs file)

Load the ES module with dynamic import()

mod.cjs
const fetch = (...args) =>
  import('node-fetch').then(({ default: fetch }) => fetch(...args));

fetch('https://example.com').then((res) => console.log(res.status));
  1. 1.

    A dependency is ESM-only and your Node.js version cannot require() it

    Packages such as node-fetch 3, chalk 5 and got 12 ship only ES modules. Before require(esm) was enabled by default, calling require() on them throws.

    How to recognise it: The path in the message is inside node_modules and the hint says "Instead change the require of index.js in ... to a dynamic import()".

  2. 2.

    Your own file is in a "type": "module" package

    A .js file whose nearest package.json has "type": "module" is loaded as an ES module. Requiring it from CommonJS throws on versions without require(esm).

    How to recognise it: The message says "is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module"" and names the package.json path.

  3. 3.

    require() of a .mjs file

    The .mjs extension is reserved for ES modules. require() of a .mjs file throws on versions without require(esm).

    How to recognise it: The path ends in .mjs and the message has no "from <parent>" part.

  4. 4.

    require(esm) is turned off

    On Node.js versions where require(esm) is on by default, ERR_REQUIRE_ESM is only thrown when it has been disabled with --no-require-module (or --no-experimental-require-module on earlier releases).

    How to recognise it: node -p "process.features.require_module" prints false on a Node.js version that should support it.

  5. 5.

    TypeScript compiled import() to require()

    With "module": "commonjs", TypeScript turns import('pkg') into Promise.resolve().then(() => require('pkg')), so a dynamic import in source still becomes a require() at runtime.

    How to recognise it: The stack points at compiled .js output, and the source file uses import() or an import statement.

1. Upgrade Node.js or check require(esm) support

When: You can run Node.js 20.19+, 22.12+ or 23+ and the ES module has no top-level await.

  1. Check the version with node -v.
  2. Check whether require(esm) is enabled with process.features.require_module.
  3. If it prints false, remove --no-require-module (or --no-experimental-require-module) from the command.
  4. require() returns the module namespace object. A default export is on .default.
node -v
node -p "process.features.require_module"

2. Replace require() with dynamic import()

When: You must stay on an older Node.js version and can load the module asynchronously.

  1. import() is available in CommonJS modules and returns a Promise of the module namespace object.
  2. Read the default export from .default.
index.cjs
async function main() {
  const { default: fetch } = await import('node-fetch');
  const res = await fetch('https://example.com');
  console.log(res.status);
}

main();

3. Install the last CommonJS major of the package

When: You need synchronous require() on an older Node.js version and do not need features from the ESM-only release.

  1. Find the last CommonJS version in the package table below.
  2. Install that major version.
npm install node-fetch@2

4. Convert your project to ES modules

When: You control the calling code and can move it to import syntax.

  1. Add "type": "module" to package.json, or rename the entry file to .mjs.
  2. Replace require() calls with import statements.
package.json
{
  "type": "module"
}

5. Set TypeScript "module" to "nodenext"

When: TypeScript output uses "module": "commonjs" and the error comes from compiled code.

  1. "module": "commonjs" transforms dynamic import() into a require() call.
  2. Under "nodenext", CommonJS output leaves import() untransformed.
  3. Since TypeScript 5.8, "nodenext" also allows require() of ES modules, matching Node.js 22.12 and later.
tsconfig.json
{
  "compilerOptions": {
    "module": "nodenext",
    "moduleResolution": "nodenext"
  }
}

6. Update Jest or run it with ESM support

When: The error appears only in Jest tests.

  1. Jest 30.4.0 added require() of ES modules on Node.js 24.9 and later.
  2. Otherwise enable Jest's experimental ESM support: set transform to {} (or configure the transformer to emit ESM) and run Node.js with --experimental-vm-modules.
Terminal
NODE_OPTIONS="$NODE_OPTIONS --experimental-vm-modules" npx jest
EnvironmentBehaviourFix
Node.js 12 to 20.18require() of an ES module throws ERR_REQUIRE_ESM. From 20.17.0, --experimental-require-module allows it.Use import(), install the last CommonJS major, or upgrade to 20.19+.
Node.js 20.19+require(esm) is enabled by default with no warning unless --trace-require-module is used.Error should not occur. Check for --no-experimental-require-module or top-level await (ERR_REQUIRE_ASYNC_MODULE).
Node.js 22.0 to 22.11Throws ERR_REQUIRE_ESM unless --experimental-require-module is passed.Upgrade to 22.12+ or pass --experimental-require-module.
Node.js 22.12+require(esm) is enabled by default. 22.12.0 emits an experimental warning unless the require() comes from node_modules. 22.13.0 removed the default warning.Error should not occur unless require(esm) is disabled.
Node.js 23+require(esm) is enabled by default from 23.0.0. The default warning was removed in 23.5.0. Marked stable in 25.4.0.Error should not occur unless require(esm) is disabled.
Node.js with --no-require-modulerequire(esm) is disabled and ERR_REQUIRE_ESM is thrown as on older versions.Remove the flag, or use import().
TypeScript "module": "commonjs"import() in source is emitted as require(), which throws on Node.js versions without require(esm).Use "module": "nodenext".
JestJest 30.4.0 supports require() of ES modules on Node.js 24.9+. The Jest docs say require() of an ESM file still throws ERR_REQUIRE_ESM on older Node.js. The Jest 30.5.0 changelog lists "Allow require() of ESM-marked files on Node < 24.9 via transform fallback".Update Jest and Node.js, or run with --experimental-vm-modules.

Node.js has two module systems. require() originally loaded CommonJS only, so requiring a .mjs file, or a .js file in a package with "type": "module", threw ERR_REQUIRE_ESM. Many packages dropped CommonJS in a major release, and CommonJS projects that upgraded them hit this error.

Node.js 22.0.0 added --experimental-require-module, which lets require() load ES modules whose graph has no top-level await. It became the default in 23.0.0, 22.12.0 and 20.19.0, and was marked stable in 25.4.0. The Node.js errors docs now list ERR_REQUIRE_ESM as deprecated.

require() of an ES module returns the module namespace object, so a default export is on .default (with __esModule: true added). A module can control what require() returns with export { X as 'module.exports' }. If the module or anything it imports uses top-level await, require() throws ERR_REQUIRE_ASYNC_MODULE and import() is needed.

DateVersionChange
16.6.0Message changed from "Must use import to load ES Module" to "require() of ES Module ... not supported." with fix hints.
22.0.0require() of synchronous ES module graphs added behind --experimental-require-module.
20.17.0--experimental-require-module backported to Node.js 20.
23.0.0require(esm) enabled by default. "module-sync" exports condition added.
22.12.0require(esm) enabled by default, with a warning unless required from node_modules.
23.5.0require(esm) warning only emitted under --trace-require-module.
22.13.0require(esm) warning only emitted under --trace-require-module.
20.19.0require(esm) enabled by default with no warning.
25.4.0require(esm) marked stable. --require-module and --no-require-module added.
26.1.0ERR_REQUIRE_ESM_RACE_CONDITION added.
PackageNote
node-fetchESM-only from 3.0.0. Last CommonJS: 2.7.0 (npm i node-fetch@2)
chalkESM-only from 5.0.0. Last CommonJS: 4.1.2 (npm i chalk@4)
gotESM-only from 12.0.0. Last CommonJS: 11.8.6 (npm i got@11)
nanoidESM-only from 4.0.0. Last CommonJS: 3.3.19 (npm i nanoid@3)
p-limitESM-only from 4.0.0. Last CommonJS: 3.1.0 (npm i p-limit@3)
oraESM-only from 6.0.0. Last CommonJS: 5.4.1 (npm i ora@5)
execaESM-only from 6.0.0. Last CommonJS: 5.1.1 (npm i execa@5)
strip-ansiESM-only from 7.0.0. Last CommonJS: 6.0.1 (npm i strip-ansi@6)
string-widthESM-only from 5.0.0. Last CommonJS: 4.2.3 (npm i string-width@4)
uuidESM-only from 12.0.0 (2025-09-05). Last CommonJS: 11.1.1 (npm i uuid@11)
inquirerESM-only from 9.0.0. CommonJS returned in 10.0.0. ESM-only again from 13.0.0. Last CommonJS: 12.11.1 (npm i inquirer@12)
or press Cmd/Ctrl + Enter. The text is only sent to this site to match it.