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.
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
- Upgrade ESLint to a version that supports flat config (ESLint 9 line).
- Keep the flat config as
eslint.config.mjswithexport default. - Re-run next lint.
npm install --save-dev eslint@latestUse 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
{ "extends": ["next/core-web-vitals"] }How to prevent it
- Match ESLint version to flat-config requirements.
- Keep ESM config files as
.mjswithexport default. - Pin ESLint and its plugins in the lockfile.