ERR_REQUIRE_ESM
Node.jsERRORCommonModule SystemHIGH confidence

Cannot use require() to load an ES Module.

Production Risk

Low. This is a startup-time error related to dependency resolution and module systems, which is nearly always resolved during development.

What this means

This error occurs when you attempt to load an ECMAScript module (ESM) using the CommonJS `require()` function. ES modules have a different loading and execution mechanism than CommonJS modules. To resolve this, you must either use dynamic `import()` in your CommonJS file or convert your file to an ES module itself.

Why it happens
  1. 1Using `require()` on a file with `.mjs` extension.
  2. 2Using `require()` on a `.js` file where the nearest package.json has type set to module.
  3. 3Attempting to load a third-party package that has fully migrated to be ESM-only.
How to reproduce

This error happens when the CommonJS loader identifies that the target file is an ES module and therefore cannot be handled synchronously by `require()`.

trigger — this will error
trigger — this will error
// Assume 'is-plain-obj' is an ESM-only package.
// This code is in a CommonJS file (e.g., index.js).
try {
  const isPlainObj = require('is-plain-obj');
} catch (err) {
  console.error(err.code);
}

expected output

ERR_REQUIRE_ESM

Fix 1

Use Dynamic import()

WHEN You need to load an ES module from a CommonJS module.

Use Dynamic import()
async function main() {
  const { default: isPlainObj } = await import('is-plain-obj');
  console.log(isPlainObj({})); // true
}
main();

Why this works

The `import()` function is asynchronous and returns a promise that resolves to the module namespace object. This is the standard way to consume ESM from CJS.

Fix 2

Convert to an ES Module

WHEN Your project can be fully migrated to use ES modules.

Convert to an ES Module
// Rename your file to 'index.mjs' or add '"type": "module"' to package.json
import isPlainObj from 'is-plain-obj';
console.log(isPlainObj({}));

Why this works

By converting your file to an ES module, you can use the static `import` syntax, which offers benefits like top-level await and static analysis.

Code examples
Triggerjs
// Assume 'is-plain-obj' is an ESM-only package.
// This code is in a CommonJS file (e.g., index.js).
try {
  const isPlainObj = require('is-plain-obj');
} catch (err) {
  console.error(err.code);  // this triggers ERR_REQUIRE_ESM
Handle in try/catchjs
try {
  // operation that may throw ERR_REQUIRE_ESM
  riskyOperation()
} catch (err) {
  if (err.code === 'ERR_REQUIRE_ESM') {
    console.error('ERR_REQUIRE_ESM:', err.message)
  } else {
    throw err
  }
}
Defensive pattern to avoid itjs
// Use dynamic import() for ESM-only packages
async function loadESM() {
  const { default: mod } = await import('esm-only-pkg')
  return mod
}
What not to do

Same error in other languages
Sources
Official documentation ↗

https://github.com/nodejs/node/blob/main/lib/internal/modules/cjs/loader.js

More information

Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev

← All Node.js errors