KBCodeKB
Next.jsUnverified

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

risk: lowofficialpublished

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.

  1. Check current Next.js version: `npx next --version`
  2. Upgrade Next.js: `npm install next@latest eslint-config-next@latest`
  3. Migrate .eslintrc.json to eslint.config.mjs using the new flat config format
  4. Remove @eslint/compat workaround if previously applied
  5. 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 eslintConfig

Risks

  • 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
0 verified0 failed

Solution 3: Use @eslint/compat fixupConfigRules (Community Workaround for ESLint 9)

risk: lowgithubpublished

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.

  1. Install dependencies: `npm install -D eslint@latest @eslint/compat @eslint/eslintrc @eslint/js globals`
  2. Create eslint.config.mjs at project root with the FlatCompat bridge
  3. Use fixupConfigRules to wrap the legacy next/core-web-vitals config
  4. Update package.json scripts to point to `next lint` (which will now recognize the flat config)
  5. 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 config

Risks

  • 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
0 verified0 failed

Solution 2: Bypass ESLint During Build (Emergency Workaround)

risk: lowgithubpublished

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.

  1. Open next.config.js (or next.config.mjs)
  2. Add the eslint.ignoreDuringBuilds option
  3. Optionally add a separate lint script that bypasses next lint entirely
  4. 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)
0 verified0 failed

Solution 1: Downgrade ESLint to v8 (Immediate Workaround)

risk: lowgithubpublished

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.

  1. Check current ESLint version: `npm ls eslint`
  2. Install ESLint v8 latest: `npm install -D eslint@^8.57.0`
  3. Remove any eslint.config.mjs flat config files if present
  4. Ensure .eslintrc.json or .eslintrc.js exists with `extends: 'next/core-web-vitals'`
  5. 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
0 verified0 failed

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"
}
← Back to all issuesPowered by CodeKB