Skip to content
Latchkey

Next.js ESLint "Must use import to load ES Module" in CI

ESLint flat config (eslint.config.mjs) and some plugins are ESM. When next lint or ESLint tries to require an ESM file in a CommonJS context, Node throws ERR_REQUIRE_ESM and the lint step fails before any rule runs.

What this error means

next lint or the lint step in next build fails with "Error [ERR_REQUIRE_ESM]: require() of ES Module ... not supported. Instead change the require ... to a dynamic import()", referencing the config or a plugin.

next lint
Error [ERR_REQUIRE_ESM]: require() of ES Module
/app/eslint.config.mjs from /app/node_modules/eslint/... not supported.
Instead change the require of eslint.config.mjs to a dynamic import().

Common causes

A CommonJS context loads an ESM ESLint config

A .mjs flat config or ESM plugin cannot be required; the loader must import it, which an older ESLint or mismatched setup does not do.

A version mismatch between ESLint and config style

Flat config requires a recent ESLint; an older version cannot load eslint.config.mjs and fails on require.

How to fix it

Align ESLint version with the config style

  1. Upgrade ESLint to a version that supports flat config (ESLint 9 line).
  2. Keep the flat config as eslint.config.mjs with export default.
  3. Re-run next lint.
Terminal
npm install --save-dev eslint@latest

Use a CommonJS config if you must stay on older tooling

If you cannot upgrade, use the legacy .eslintrc.json format that does not require ESM loading.

.eslintrc.json
// .eslintrc.json
{ "extends": ["next/core-web-vitals"] }

How to prevent it

  • Match ESLint version to flat-config requirements.
  • Keep ESM config files as .mjs with export default.
  • Pin ESLint and its plugins in the lockfile.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →