ESLint 10 Killed .eslintrc — Here's the Flat Config You Need Now
Any project upgrading to ESLint 10 will break silently until `.eslintrc` is replaced with an `eslint.config.mjs` file. The migration is mechanical but unforgiving: forgetting `globals` floods the output with `no-undef` errors, and mixing `"type": "commonjs"` with `.mjs` configs causes module resolution failures.
The `.eslintrc` format and its cascade resolution are gone as of ESLint 10. The replacement, flat config, exports a plain JS array of configuration objects. Each object declares its own file scope, plugins, and rules; the array order is the override order, eliminating the implicit merging that made old configs unpredictable. Built-in recommended rules now ship as the `@eslint/js` package, and environment globals require the separate `globals` package — two dependencies that catch most migration attempts. A live demo shows that `js/recommended` catches real bugs like unused variables, while formatting rules stay silent until you violate them, and `--fix` only touches style rules, not logic errors.
The cascade system's real cost was not performance but unpredictability: developers could not tell which config file a final rule came from, making debugging a guessing game.
Flat config's design shifts ESLint from a 'convention over configuration' tool toward an explicit module graph, which raises the initial setup cost but eliminates an entire class of silent misconfiguration bugs.
The split of built-in rules into `@eslint/js` and globals into a separate `globals` package suggests the ESLint team is unbundling the core to make the dependency surface visible and auditable.
Many developers will discover their old configs never actually enforced the rules they thought they did, because cascade merging silently overrode them — flat config makes that visible immediately.