Skip to content

fix(lint): native flat config for eslint-config-next 16, drop next lint - #85

Open
lacymorrow wants to merge 1 commit into
mainfrom
fix/eslint-flat-config
Open

lacymorrow wants to merge 1 commit into
mainfrom
fix/eslint-flat-config

Conversation

@lacymorrow

Copy link
Copy Markdown
Contributor

One sentence

Makes ESLint runnable again after the Next 16 bump by importing eslint-config-next 16 flat configs directly and replacing the removed next lint command; not a dependency bump, so left open for review.

Why

Found while attempting the ESLint 10 major for LAC-3869. On main, pnpm lint:eslint runs next lint, which Next 16 removed (https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/upgrading/version-16.mdx). Running eslint directly also crashes: eslint-config-next 16 exports native flat-config arrays and FlatCompat.extends("next/core-web-vitals") fails with Converting circular structure to JSON.

Changes

Package From To
typescript-eslint (new devDependency) not declared (8.52.0 transitive) 8.70.0
@eslint/eslintrc 3.3.7 removed
eslint 9.39.2 9.39.5 (in-range patch)
  • eslint.config.mjs: imports eslint-config-next/core-web-vitals and eslint-config-next/typescript directly (the way the Next 16 docs show) and applies typescript-eslint recommendedTypeChecked + stylisticTypeChecked, the same presets FlatCompat used to pull in. Rule overrides and ignores are unchanged.
  • Type-aware rules are disabled (tseslint.configs.disableTypeChecked) for the paths tsconfig.json excludes (scripts/, tests/, src/workers/, (ai), (demo)/examples, *.config.ts, *.config.*.ts); those files produced "parserOptions.project" has been provided parse errors before.
  • lint:eslint -> eslint ., lint:fix:eslint -> eslint . --fix.

Result

pnpm lint:eslint now completes: 75 errors and 124 warnings, all pre-existing code findings (24 prefer-nullish-coalescing, 10 no-unnecessary-type-assertion, 8 no-explicit-any, 4 require-await, 4 no-require-imports, 2 react/no-unescaped-entities, 2 react/display-name, ...). Fixing them is separate work, so pnpm lint still exits non-zero, but it now says why instead of crashing.

ESLint 10 is still blocked

With this config and eslint@10.10.0, linting any component crashes in react/display-name: contextOrFilename.getFilename is not a function. eslint-config-next@16.3.5 depends on eslint-plugin-react@^7.37.0; 7.37.5 (April 2025) is the latest release and still uses context.getFilename(), which ESLint 10 removed. Its peer range is eslint ^3 ... ^9.7; eslint-plugin-import and eslint-plugin-jsx-a11y also cap at ^9. Until eslint-plugin-react ships ESLint 10 support and eslint-config-next picks it up, ESLint 10 cannot be adopted here. Source: https://github.com/eslint/eslint/blob/main/docs/src/use/migrate-to-10.0.0.md

Verification

  • pnpm typecheck clean
  • pnpm test: 4 files, 16 tests green
  • pnpm exec vitest run --config vitest.config.node.ts: 3 files, 21 tests green
  • pnpm build passes
  • next start smoke: / 200, /changelog 200, /changelog/nope-xyz 404, /faq 200, /nope-404 404

Installed with --ignore-scripts (isolated-vm postinstall fails under Node 26 locally; matches how Vercel builds).

https://claude.ai/code/session_01KLWmWU1KLE2diUH14ryqv1

ESLint has not been runnable on main since the Next 16 bump:
- `next lint` was removed in Next 16, so `pnpm lint:eslint` fails immediately
- eslint-config-next 16 ships native flat configs, and FlatCompat cannot
  convert them ("Converting circular structure to JSON")

Changes:
- eslint.config.mjs imports eslint-config-next/core-web-vitals and
  eslint-config-next/typescript directly and uses typescript-eslint's
  recommendedTypeChecked + stylisticTypeChecked (same presets as before)
- type-aware rules are disabled for files tsconfig.json excludes (scripts/,
  tests/, src/workers/, (ai), (demo)/examples, *.config.ts), which previously
  produced "parserOptions.project" parse errors
- lint:eslint / lint:fix:eslint now run `eslint .`
- typescript-eslint 8.70.0 added as a direct devDependency; @eslint/eslintrc
  removed (no longer used)

`pnpm lint:eslint` now runs to completion: 75 errors, 124 warnings, all
pre-existing code findings (prefer-nullish-coalescing, no-unnecessary-type-
assertion, no-explicit-any, ...). Fixing those is separate work.

This is groundwork for ESLint 10, which is still blocked: eslint-config-next
depends on eslint-plugin-react 7.37.5, whose rules call context.getFilename(),
removed in ESLint 10 ("react/display-name: contextOrFilename.getFilename is not
a function"). No eslint-plugin-react release supports ESLint 10 yet.

Claude-Session: https://claude.ai/code/session_01KLWmWU1KLE2diUH14ryqv1
@vercel

vercel Bot commented Sep 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
bones Ready Ready Preview Sep 14, 2026 3:56pm UTC

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant