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().
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.
Wrap the ESM dependency in a helper that uses import(), which works from CommonJS:
// 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.
If your React project can move to ESM, update package.json:
{
"type": "module"
}Then replace require() with import/ export and include extensions on relative imports:
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.
Temporarily downgrade the dependency until you can migrate tooling:
npm install [email protected]
npm install [email protected]
# or, with yarn:
# yarn add node-fetch@^2.6.7 strip-ansi@^6.0.1Node-fetch v2 and strip-ansi v6 are still CommonJS. Use overrides or Yarn resolutions if the package is pulled in transitively:
{
"overrides": {
"strip-ansi": "6.0.1"
}
}This lets the build succeed while you plan a permanent fix.
If the project uses "type": "module" but builds still require CommonJS configs (Webpack, Jest), rename them to .cjs:
mv webpack.config.js webpack.config.cjs
mv jest.config.js jest.config.cjsThen update your package.json scripts:
{
"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.
Configure Webpack or Vite to handle .mjs and conditional exports so it can load ESM packages cleanly:
// 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.
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.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite