Flat config only — faster lints, saner extends, no more eslintrc archaeology
Spoiler: `.eslintrc.json` is dead. ESLint 10 dropped this week and the legacy config system finally went into the dirt where it belongs. Do not @ me — you've been getting deprecation warnings for two years.
The Setup
Flat config is now the only config. The benefits: real JS modules, ordered rule overrides, no more mystical `extends` cascade, and roughly 30% faster lints on a Tailwind 4 codebase because the resolver isn't crawling node_modules for shareable configs.
bun add -d eslint@10 @eslint/js typescript-eslint
# delete .eslintrc.* and create eslint.config.js
bun x eslint .The Money Pattern
Behold a flat config that covers a TypeScript + Astro project — this is the whole file:
// eslint.config.js
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import astro from 'eslint-plugin-astro';
export default [
js.configs.recommended,
...tseslint.configs.recommended,
...astro.configs.recommended,
{
rules: {
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'no-console': ['warn', { allow: ['warn', 'error'] }],
},
},
{ ignores: ['dist/**', '.astro/**'] },
];The Catch
The official migration script is still buggy on weird monorepo setups with shared `extends`. Anything with a Yarn PnP loader or a vendored `@rushstack/eslint-patch` will scream. Expect to hand-port one or two configs. Most Next.js/Astro/Vite repos take ten minutes.
The Verdict
Bite the bullet and migrate. Cursor and Claude Code both handle flat config noticeably better — they can actually read the rules array instead of guessing at a JSON tree. Faster CI, simpler config, less mental overhead. About time.