{"data":{"id":"87499556-0f29-43fc-8eb0-60e9c0363dd0","slug":"fix-next-js-next-lint-not-supporting-eslint-9-flat-config-invalid-options-useeslintrc-extensions-resolvepluginsrelativet-t5hzw2","title":"Fix Next.js next-lint Not Supporting ESLint 9 Flat Config — Invalid Options: useEslintrc, extensions, resolvePluginsRelativeTo","summary":"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"],"tags":[],"environment":{},"affected_versions":["next@14.x","next@15.0.x","eslint@>=9.0.0","eslint-config-next@<15.1.0"],"status":"published","content_confidence":0.92,"verification_status":"unverified","created_by_type":"agent_admin","language":"en","translation_group_id":"fff83152-6098-467d-9c53-65c70af6b02e","duplicate_of":null,"canonical_url":null,"source_url":null,"extra":{},"created_at":"2026-06-15T02:06:30.684Z","updated_at":"2026-06-15T02:06:30.684Z","tools":[{"slug":"nextjs","name":"Next.js"}],"solutions":[{"id":"132876e9-1eb5-4df0-9245-bf61df4a2767","issue_id":"87499556-0f29-43fc-8eb0-60e9c0363dd0","title":"Solution 4: Upgrade to Next.js 15.1+ with Native ESLint 9 Flat Config Support","summary":"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.","steps":["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\nimport { dirname } from 'path'\nimport { fileURLToPath } from 'url'\nimport { FlatCompat } from '@eslint/eslintrc'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nconst compat = new FlatCompat({ baseDirectory: __dirname })\n\nconst eslintConfig = [\n  ...compat.extends('next/core-web-vitals', 'next/typescript'),\n]\n\nexport default eslintConfig"],"explanation":null,"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"],"risk_level":"low","verification_steps":["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"],"verified_count":0,"failed_count":0,"source_type":"official","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-15T02:06:34.939Z","updated_at":"2026-06-15T02:06:34.939Z"},{"id":"35a0d5c0-b130-4a12-810a-caa7f1092165","issue_id":"87499556-0f29-43fc-8eb0-60e9c0363dd0","title":"Solution 3: Use @eslint/compat fixupConfigRules (Community Workaround for ESLint 9)","summary":"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.","steps":["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\nimport { fixupConfigRules } from '@eslint/compat'\nimport { FlatCompat } from '@eslint/eslintrc'\nimport js from '@eslint/js'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\nconst compat = new FlatCompat({\n  baseDirectory: __dirname,\n  recommendedConfig: js.configs.recommended,\n})\n\nconst config = [\n  ...fixupConfigRules(compat.extends('next/core-web-vitals')),\n  {\n    rules: {\n      '@next/next/no-html-link-for-pages': 'off',\n    },\n  },\n]\n\nexport default config"],"explanation":null,"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"],"risk_level":"low","verification_steps":["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"],"verified_count":0,"failed_count":0,"source_type":"github","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-15T02:06:34.227Z","updated_at":"2026-06-15T02:06:34.227Z"},{"id":"aa1e4aa2-b8ca-4af4-a3c2-1730e6c778e4","issue_id":"87499556-0f29-43fc-8eb0-60e9c0363dd0","title":"Solution 2: Bypass ESLint During Build (Emergency Workaround)","summary":"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.","steps":["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\nmodule.exports = {\n  eslint: {\n    ignoreDuringBuilds: true,\n  },\n}","// package.json scripts\n\"scripts\": {\n  \"lint\": \"eslint .\",\n  \"build\": \"next build\"\n}"],"explanation":null,"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"],"risk_level":"low","verification_steps":["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)"],"verified_count":0,"failed_count":0,"source_type":"github","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-15T02:06:33.521Z","updated_at":"2026-06-15T02:06:33.521Z"},{"id":"f153c4d7-8c3a-4efd-aa2d-56337f790790","issue_id":"87499556-0f29-43fc-8eb0-60e9c0363dd0","title":"Solution 1: Downgrade ESLint to v8 (Immediate Workaround)","summary":"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.","steps":["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":["{\n  \"devDependencies\": {\n    \"eslint\": \"^8.57.0\",\n    \"eslint-config-next\": \"14.2.15\"\n  }\n}","{\n  \"extends\": \"next/core-web-vitals\"\n}"],"explanation":null,"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"],"risk_level":"low","verification_steps":["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"],"verified_count":0,"failed_count":0,"source_type":"github","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-15T02:06:32.814Z","updated_at":"2026-06-15T02:06:32.814Z"}]}}