Node.js "Cannot find module 'node-fetch'" (ESM-only v3) in CI
node-fetch v3+ is published as ESM only. CommonJS code that require("node-fetch") either cannot resolve it or throws ERR_REQUIRE_ESM, breaking the build.
What this error means
After upgrading node-fetch, a CommonJS project fails on require("node-fetch") with a module-not-found or ERR_REQUIRE_ESM error in CI.
node
Error [ERR_REQUIRE_ESM]: require() of ES Module
/work/repo/node_modules/node-fetch/src/index.js from
/work/repo/src/http.js not supported.
code: 'ERR_REQUIRE_ESM'Common causes
node-fetch v3 dropped CommonJS
Version 3 ships ESM only. A CommonJS project that upgrades can no longer require it synchronously.
Native fetch makes node-fetch unnecessary
Modern Node has a global fetch. Keeping node-fetch at all is often avoidable and the source of the ESM mismatch.
How to fix it
Use the built-in global fetch
Drop the dependency entirely on Node 18+, which provides fetch globally.
src/http.js
// remove node-fetch import
const res = await fetch('https://example.com');
const data = await res.json();Or pin node-fetch v2 for CommonJS
If you must keep node-fetch in a CommonJS project, pin v2, which still ships CommonJS.
Terminal
npm install node-fetch@2How to prevent it
- Prefer the global
fetchon Node 18+ and remove node-fetch. - Read changelogs for ESM-only majors before upgrading.
- Keep one module system across the project.
Related guides
Node.js "Must use import to load ES Module" (CJS requiring ESM) in CIFix ERR_REQUIRE_ESM "Must use import to load ES Module" in CI - a CommonJS file called require() on a depende…
Node.js "TypeError: fetch failed" (undici) in CIFix "TypeError: fetch failed" from Node's built-in undici fetch in CI - a low-level network, DNS, or TLS fail…
Node ERR_REQUIRE_ESM "Must use import to load ES Module" - Fix in CIFix Node ERR_REQUIRE_ESM "require() of ES Module not supported" in CI - a CommonJS require of an ESM-only pac…