Node.js "ERR_REQUIRE_ESM" — require() Against an ESM-Only Package

The package you required ships only ES modules; require() can't load it. Your choices: migrate the file to ESM, downgrade the dependency, or use a dynamic import bridge.

What you'll see

Root causes

Dependency's newer major dropped CommonJS

Pure-ESM packages declare "type": "module" / "exports" with import-only paths. require() of them throws by design in modern Node.

Your project is CommonJS and you upgraded the dependency

npm install <pkg>@latest crossed the CJS→ESM boundary of that package. The lockfile pinning the old version is why CI was fine before.

Fix it

  1. Downgrade to the last CJS major (fastest unblock)
    npm install chalk@4   # or the equivalent CJS-compatible major for the offending package
  2. Or migrate the consuming file to ESM
    # rename to .mjs (or set package.json "type": "module") and use: import chalk from 'chalk';
  3. Bridge: dynamic import from CommonJS
    // const { default: chalk } = await import('chalk');  (inside an async function)
  4. Verify the package's module type before upgrading
    node -e "console.log(require('./node_modules/<pkg>/package.json').type || 'commonjs')"

Field note

Mixed repos: use .mjs/.cjs extensions per file instead of a blanket "type": "module" — explicit beats implicit during migration. Pure-ESM is a direction, not a fad: plan the migration on your schedule rather than one forced by an upgrade.

Common questions

Why do bundlers/transpilers handle it but plain Node fails?

Webpack/esbuild/jest transform imports to a format require() can consume. Plain Node enforces the real module system. Test the production path (node directly), not just the dev path.

Is downgrading the dependency a real fix?

It's a legitimate stopgap: pin the last CJS major while you plan the ESM migration. Check the old major still receives security patches before parking on it long-term.

Ship it right the first time

Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.

Browse the template store →

One-time. Yours to modify. Instant download from the NinjaOps template store.