How to fix Error [ERR_REQUIRE_ESM]: require() of ES Module not supported in React

ReactINTERMEDIATEMEDIUMUpdated Dec 10, 2025ยท 142 views

A React build or runtime throws "require() of ES modules is not supported" when CommonJS code tries to load an ES module (for example node-fetch v3 or strip-ansi v7) because Node enforces module system compatibility and CRA/Next builds still emit require().

Quick fix

Fixes ERR_REQUIRE_ESM

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

module.exports = { fetch };

// usage
const { fetch } = require('./fetch-wrapper.cjs');
fetch(url).then((result) => result.json());
  1. Load the ESM-only package with dynamic import()
  2. Convert React tooling to ESM (package.json "type": "module")
  3. Pin the last CommonJS-friendly version of the dependency
  4. Ensure configuration files stay CommonJS with .cjs extensions
react โ€” error
// fetch-wrapper.cjs
const fetch = (...args) =>
import('node-fetch').then(({ default: fetch }) => fetch(...args));
module.exports = { fetch };
// usage
const { fetch } = require('./fetch-wrapper.cjs');
fetch(url).then((result) => result.json());
Error [ERR_REQUIRE_ESM]: require() of ES Module not supported

What this error means

Node.js keeps CommonJS (`require()`) and ES Modules (`import`) intentionally separate. When a package, like node-fetch v3 or strip-ansi v7, declares itself as ESM-only (via "type": "module" or a .mjs entry), Node refuses to load it with `require()` and raises ERR_REQUIRE_ESM. Bundlers such as Create React App, Next.js, or custom Webpack configs still emit CommonJS-style loading for server-side code, so the runtime hits this error as soon as an ESM-only dependency is pulled into a CommonJS loader. In React stacks, this often surfaces when dependencies are upgraded to ESM-only releases. Node-fetch switched to ESM in the 3.0.0 beta, while strip-ansi 7.0 made the same leap. Even if your source files are still CommonJS, transitive imports from your build or CLI tooling can end up inside a CommonJS context and trigger the error. Fixing it requires either adopting ES modules across the app, loading ESM dependencies asynchronously, or pinning to the latest CommonJS-friendly version.

Typical symptoms

  • React dev server or build fails with "Error [ERR_REQUIRE_ESM]: require() of ES Module not supported"
  • Server-side rendering (Next.js API routes / pages) crashes before the first render
  • Unit tests break with "Must use import to load ES Module" messages
  • Console output shows the offending package path (node_modules/node-fetch or strip-ansi)
  • CI job that bundles the React app fails during npm install or webpack compile
  • Dependencies that previously worked start failing after a patch release

Common causes

  1. An ESM-only package (node-fetch v3+, strip-ansi v7, chalk v5+) is being require()-loaded
  2. "type": "module" is set in a dependency, but the consuming code still uses require()
  3. React build tooling emits CommonJS wrappers around ESM dependencies (e.g., CRA server.js)
  4. Mixed module syntax where helper scripts remain CommonJS while new code uses import
  5. Bundler config does not list .mjs/.cjs extensions or cannot handle asynchronous imports
  6. Transitive dependency upgrade (strip-ansi, node-fetch, ansi-styles) introduced ESM-only artifacts

How to fix "Error [ERR_REQUIRE_ESM]: require() of ES Module not supported"

1Load the ESM-only package with dynamic import()

Wrap the ESM dependency in a helper that uses import(), which works from CommonJS:

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

module.exports = { fetch };

// usage
const { fetch } = require('./fetch-wrapper.cjs');
fetch(url).then((result) => result.json());

Node-fetch 3+ dropped CommonJS in favor of ES modules, so require('node-fetch') now throws ERR_REQUIRE_ESM. Use this wrapper to keep the rest of your code CommonJS while loading the module asynchronously.

2Convert React tooling to ESM (package.json "type": "module")

If your React project can move to ESM, update package.json:

json
{
  "type": "module"
}

Then replace require() with import/ export and include extensions on relative imports:

javascript
import React from 'react';
import App from './App.js';
export default App;

Update build scripts (Webpack, Babel, jest) to handle .js/.jsx/.mjs/.cjs and enable module: "ES2020", moduleResolution: "node" in tsconfig. Next.js and CRA also support ESM entry files for API routes once they export with export default.

3Pin the last CommonJS-friendly version of the dependency

Temporarily downgrade the dependency until you can migrate tooling:

bash
npm install node-fetch@2.6.7
npm install strip-ansi@6.0.1
# or, with yarn:
# yarn add node-fetch@^2.6.7 strip-ansi@^6.0.1

Node-fetch v2 and strip-ansi v6 are still CommonJS. Use overrides or Yarn resolutions if the package is pulled in transitively:

json
{
  "overrides": {
    "strip-ansi": "6.0.1"
  }
}

This lets the build succeed while you plan a permanent fix.

4Ensure configuration files stay CommonJS with .cjs extensions

If the project uses "type": "module" but builds still require CommonJS configs (Webpack, Jest), rename them to .cjs:

bash
mv webpack.config.js webpack.config.cjs
mv jest.config.js jest.config.cjs

Then update your package.json scripts:

json
{
  "scripts": {
    "build": "webpack --config webpack.config.cjs"
  }
}

Files ending with .cjs are always interpreted as CommonJS, letting tooling still call require() without hitting ERR_REQUIRE_ESM.

5Teach the bundler to resolve multiple extensions and conditional exports

Configure Webpack or Vite to handle .mjs and conditional exports so it can load ESM packages cleanly:

javascript
// webpack.config.js
module.exports = {
  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs'],
    conditionNames: ['require', 'import', 'default']
  }
};

If a package.json exposes both import and require entry points, the bundler must pick the right one. Webpack 5 and Vite do this automatically if you include .mjs in resolve extensions and avoid forcing mainFields to CommonJS-only entries.

Advanced notes

Node 18+ now ships with the WHATWG fetch API, so React servers running on a modern Node version can drop node-fetch entirely. For other runtimes, packages such as Got, Axios, or isomorphic-fetch stay CommonJS. When migrating, be careful with dual-package distributions: importing the ESM entry in some places and the CJS entry elsewhere can create duplicate instances, which breaks checks like instanceof React.Component. Finally, tools like esm-hook or ts-node --esm can smooth the transition but add extra transpilation steps.

Frequently asked questions

What does "ERR_REQUIRE_ESM" mean?
js keeps CommonJS (require()) and ES Modules (import) intentionally separate. mjs entry), Node refuses to load it with require() and raises ERR_REQUIRE_ESM. js, or custom Webpack configs still emit CommonJS-style loading for server-side code, so the runtime hits this error as soon as an ESM-only dependency is pulled into a CommonJS loader.
How do I fix "ERR_REQUIRE_ESM"?
A React build or runtime throws "require() of ES modules is not supported" when CommonJS code tries to load an ES module (for example node-fetch v3 or strip-ansi v7) because Node enforces module system compatibility and CRA/Next builds still emit require().
What causes "ERR_REQUIRE_ESM"?
An ESM-only package (node-fetch v3+, strip-ansi v7, chalk v5+) is being require()-loaded "type": "module" is set in a dependency, but the consuming code still uses require() React build tooling emits CommonJS wrappers around ESM dependencies (e.g., CRA server.js)
Is the "ERR_REQUIRE_ESM" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading