Fix Next.js next-lint Not Supporting ESLint 9 Flat Config — Invalid Options: useEslintrc, extensions, resolvePluginsRelativeTo
When upgrading ESLint from v8 to v9, Next.js's `next lint` command breaks with 'Invalid Options: Unknown options: useEslintrc, extensions, resolvePluginsRelativeTo, rulePaths, ignorePath, reportUnusedDisableDirectives' errors. This happens because ESLint 9 removed these legacy CLI flags in favor of the new flat config system, but Next.js's internal ESLint runner still passes them. Four solutions: downgrade ESLint to v8, use `eslint.ignoreDuringBuilds` in next.config.js, apply the @eslint/compat fixupConfigRules community workaround, or use the official eslint-config-next release with ESLint 9 support (Next.js 15.1+).
Symptoms
- `next lint` fails with 'Invalid Options: - Unknown options: useEslintrc, extensions' when ESLint 9.x is installed
- 'extensions has been removed', 'resolvePluginsRelativeTo has been removed', 'ignorePath has been removed' errors during lint
- `next build` fails at the linting stage with ESLint 9, blocking CI/CD pipelines
- ESLint 8 EOL is October 2024 — projects stuck on unsupported ESLint version due to Next.js incompatibility
- eslint.config.mjs flat config files not recognized by next lint when using ESLint 9
- Dependabot/Renovate PRs upgrading eslint to v9 fail CI due to next lint incompatibility
Error signatures
Invalid Options: - Unknown options: useEslintrc, extensions
'extensions' has been removed
'resolvePluginsRelativeTo' has been removed
'ignorePath' has been removed
'rulePaths' has been removed
'reportUnusedDisableDirectives' has been removed
Possible causes
- ESLint 9.0.0 removed CLI flags (useEslintrc, extensions, resolvePluginsRelativeTo, ignorePath, rulePaths, reportUnusedDisableDirectives) that Next.js's internal ESLint runner still passes to the ESLint API
- Next.js packages/next/src/cli/next-lint.ts hardcodes legacy ESLint options that don't exist in ESLint 9's flat config API
- eslint-config-next peer dependency range is `^7.23.0 || ^8.0.0`, explicitly excluding ESLint 9 — npm installs ESLint 9 anyway because Next.js does not pin the version
- Several eslint plugins used by eslint-config-next (eslint-plugin-import, eslint-plugin-react-hooks, etc.) lagged in shipping ESLint 9 flat config support, blocking the Next.js team from upgrading the internal lint runner
Solutions
Solution 4: Upgrade to Next.js 15.1+ with Native ESLint 9 Flat Config Support
Next.js 15.1+ ships with first-class ESLint 9 flat config support in eslint-config-next. This is the long-term, officially supported path — upgrade Next.js and migrate your ESLint config to the flat config format.
- Check current Next.js version: `npx next --version`
- Upgrade Next.js: `npm install next@latest eslint-config-next@latest`
- Migrate .eslintrc.json to eslint.config.mjs using the new flat config format
- Remove @eslint/compat workaround if previously applied
- Verify with `npx next lint`
Commands
npm install next@latest eslint-config-next@latest
npx next lint
Config examples
// eslint.config.mjs — Next.js 15.1+ native format
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import { FlatCompat } from '@eslint/eslintrc'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const compat = new FlatCompat({ baseDirectory: __dirname })
const eslintConfig = [
...compat.extends('next/core-web-vitals', 'next/typescript'),
]
export default eslintConfigRisks
- Next.js 15.1 may introduce other breaking changes beyond ESLint (React 19, Turbopack, etc.)
- Custom eslintrc-based configs and plugins in existing projects need individual migration to flat config
Verification
- Run `npx next lint` → expected: completes successfully with ESLint 9.x, no compatibility warnings
- Run `npm ls eslint` → expected: eslint@9.x.x is listed as a dependency
- Check that all your custom ESLint plugins work — test with `eslint .` directly
Solution 3: Use @eslint/compat fixupConfigRules (Community Workaround for ESLint 9)
The @eslint/compat package provides fixupConfigRules() and fixupPluginRules() that bridge the gap between legacy eslintrc configs and ESLint 9's flat config. This lets you use eslint-config-next with ESLint 9 by wrapping the config in a compatibility layer.
- Install dependencies: `npm install -D eslint@latest @eslint/compat @eslint/eslintrc @eslint/js globals`
- Create eslint.config.mjs at project root with the FlatCompat bridge
- Use fixupConfigRules to wrap the legacy next/core-web-vitals config
- Update package.json scripts to point to `next lint` (which will now recognize the flat config)
- Test with `npx next lint` and `npx next build`
Commands
npm install -D eslint@latest @eslint/compat @eslint/eslintrc @eslint/js globals
npx next lint
Config examples
// eslint.config.mjs
import { fixupConfigRules } from '@eslint/compat'
import { FlatCompat } from '@eslint/eslintrc'
import js from '@eslint/js'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
})
const config = [
...fixupConfigRules(compat.extends('next/core-web-vitals')),
{
rules: {
'@next/next/no-html-link-for-pages': 'off',
},
},
]
export default configRisks
- Some ESLint 9 plugins may still produce deprecation warnings in console output
- @eslint/compat is a migration helper, not a permanent solution — it may be deprecated once eslint-config-next ships flat config natively
- Custom eslintrc-based plugins in your project may need individual fixupPluginRules wrapping
Verification
- Run `npx next lint` → expected: lint completes without 'Invalid Options' errors, lists actual lint warnings/errors from your code
- Run `npx next build` → expected: build succeeds, lint stage passes
- Introduce a deliberate lint error (e.g., unused variable) and verify it's caught
Solution 2: Bypass ESLint During Build (Emergency Workaround)
Configure Next.js to skip ESLint during `next build` by setting `eslint.ignoreDuringBuilds: true` in next.config.js. This allows builds to succeed while ESLint 9 is installed, but you lose automated lint checking in CI.
- Open next.config.js (or next.config.mjs)
- Add the eslint.ignoreDuringBuilds option
- Optionally add a separate lint script that bypasses next lint entirely
- Commit and redeploy
Commands
npx next build
Config examples
// next.config.js
module.exports = {
eslint: {
ignoreDuringBuilds: true,
},
}// package.json scripts
"scripts": {
"lint": "eslint .",
"build": "next build"
}Risks
- Linting errors won't block builds — bugs that would have been caught by lint may reach production
- Team members may not run lint locally, leading to inconsistent code quality
Verification
- Run `npx next build` with ESLint 9 installed → expected: build succeeds without lint errors
- Check that next lint still fails when run directly (expected — this only bypasses the build step)
Solution 1: Downgrade ESLint to v8 (Immediate Workaround)
Pin ESLint to v8.x in package.json to match eslint-config-next's peer dependency range. This is the simplest and most reliable fix until full ESLint 9 support ships.
- Check current ESLint version: `npm ls eslint`
- Install ESLint v8 latest: `npm install -D eslint@^8.57.0`
- Remove any eslint.config.mjs flat config files if present
- Ensure .eslintrc.json or .eslintrc.js exists with `extends: 'next/core-web-vitals'`
- Run `next lint` to verify it works
Commands
npm install -D eslint@^8.57.0
npx next lint
Config examples
{
"devDependencies": {
"eslint": "^8.57.0",
"eslint-config-next": "14.2.15"
}
}{
"extends": "next/core-web-vitals"
}Risks
- ESLint 8 reached EOL in October 2024 — no more security patches or bug fixes
- New ESLint 9 rules and plugins won't be available
Verification
- Run `npm ls eslint` → expected: eslint@8.x.x (not 9.x.x)
- Run `npx next lint` → expected: lint completes without 'Invalid Options' or 'has been removed' errors
- Run `npx next build` → expected: build passes the lint stage
Agent JSON
Canonical machine-readable representation of this issue:
{
"issue_id": "87499556-0f29-43fc-8eb0-60e9c0363dd0",
"slug": "fix-next-js-next-lint-not-supporting-eslint-9-flat-config-invalid-options-useeslintrc-extensions-resolvepluginsrelativet-t5hzw2",
"verification_status": "unverified",
"canonical_json": "https://codekb.dev/v1/issues/fix-next-js-next-lint-not-supporting-eslint-9-flat-config-invalid-options-useeslintrc-extensions-resolvepluginsrelativet-t5hzw2"
}