The error, verbatim
Jump to the fix ↓Oops! Something went wrong! :(
ESLint: 10.12.0
ESLint couldn't find an eslint.config.* file.
From ESLint v9.0.0, the default configuration file is now eslint.config.*.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:
Tested on
- eslint
- 10.12.0 and 9.39.5
- @eslint/js / globals
- 10.0.1 / 14.0.0
- eslint-config-next
- 16.4.0 (with next 16.4.0)
- Node / npm / OS
- 24.14.0 / 11.9.0 / Windows 11 Pro
✓ Re-verified on eslint v10.14.0, eslint-plugin-react 7.37.5 (Linux): 3/3 checks still hold · results
Contents
This error means ESLint looked for a config file in the new format and found none. Usually there is a config: an .eslintrc.json, .eslintrc.js or .eslintrc.yml that worked for years. ESLint 9 made eslint.config.* the default, and ESLint 10 removed support for .eslintrc completely, so that file is now simply ignored.
I reproduced it with a project that had only an .eslintrc.json, on both versions:
| ESLint 9.39.5 | ESLint 10.12.0 | |
|---|---|---|
| Message | couldn't find an eslint.config.(js|mjs|cjs) file |
couldn't find an eslint.config.* file |
ESLINT_USE_FLAT_CONFIG=false |
Still loads .eslintrc, with a deprecation warning |
Ignored: same error |
ESLint 10 also exits with code 2, so CI fails on this step. There’s no switch that brings the old format back. The config has to move.
The fix
The quickest way is ESLint’s own converter, run in the folder with your old config:
npx @eslint/migrate-config .eslintrc.jsonIt writes eslint.config.mjs and prints the packages the new file imports. Install exactly those. For my config it asked for:
npm install -D @eslint/js @eslint/eslintrcThe converted file wraps your old settings in a compatibility layer (FlatCompat). That’s fine, but for a small config a hand-written file is shorter and has no compatibility package:
import js from "@eslint/js";
import globals from "globals";
import { defineConfig } from "eslint/config";
export default defineConfig([
js.configs.recommended,
{ languageOptions: { globals: globals.node } },
]);“‘console’ is not defined” after migrating
The next surprise is a flood of no-undef errors for things that obviously exist:
2:1 error 'console' is not defined no-undef
.eslintrc had env: { node: true } or env: { browser: true } to declare those globals. Flat config has no env.
The globals come from the globals package now. The converter handles it when the old file had an env: it turned node: true into ...globals.node and asked me to install globals. A hand-written config needs it explicitly, which is the languageOptions.globals line in the config above. Use globals.browser for front-end code.
ESLint 10 with React and Next.js plugins
This is the part behind most “eslint 10” searches. Several of the most-used plugins don’t declare support for ESLint 10 yet. Their peerDependencies on October 10, 2026:
| Plugin | Version | Declares ESLint 10? |
|---|---|---|
| eslint-plugin-react | 7.37.5 | ❌ up to ^9.7 |
| eslint-plugin-import | 2.32.0 | ❌ up to ^9 |
| eslint-plugin-jsx-a11y | 6.10.2 | ❌ up to ^9 |
| eslint-plugin-react-hooks | 7.1.1 | ✅ |
| typescript-eslint | 8.71.1 | ✅ |
| eslint-plugin-vue | 10.11.1 | ✅ |
| eslint-config-next | 16.4.0 | ✅ >=9.0.0, but it depends on the first three |
How that showed up depended on how the plugin got into the project. Installing eslint-plugin-react directly next to ESLint 10 failed outright, and nothing was installed:
npm error code ERESOLVE
npm error Found: eslint@10.12.0
npm error Could not resolve dependency:
npm error peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" from eslint-plugin-react@7.37.5
Through eslint-config-next, npm only warned (npm warn ERESOLVE overriding peer dependency, three times) and installed everything.
In both cases the plugins worked on ESLint 10. With eslint-config-next’s core-web-vitals config, a test file got errors and warnings from react/jsx-key, react-hooks/rules-of-hooks, jsx-a11y/alt-text and @next/next/no-img-element, so all of those plugins loaded and ran. The block is the declared version range, not the code.
To install a plugin that hasn’t declared ESLint 10 yet, tell npm to accept your ESLint for it, in package.json:
{
"overrides": {
"eslint-plugin-react": { "eslint": "$eslint" }
}
}npm install --legacy-peer-deps also worked, but it has to be repeated on every install and in CI. The override stays in the project. Remove it when the plugin publishes ESLint 10 support.
“‘React’ must be in scope when using JSX”
If you set up eslint-plugin-react by hand with its recommended config, every JSX file gets this:
2:10 error 'React' must be in scope when using JSX react/react-in-jsx-scope
The recommended config still assumes the old JSX transform from before React 17.
Add the plugin’s jsx-runtime config after the recommended one:
import react from "eslint-plugin-react";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.jsx"],
...react.configs.flat.recommended,
...react.configs.flat["jsx-runtime"],
rules: { ...react.configs.flat.recommended.rules, ...react.configs.flat["jsx-runtime"].rules },
settings: { react: { version: "19.0" } },
},
]);One more thing if you’re on Next.js: create-next-app 16.4 with its defaults no longer adds ESLint at all, so there’s no lint script or config to migrate. You add both yourself.
What didn’t work
How this was tested
Fresh npm projects on Windows 11 with Node 24.14.0 and npm 11.9.0:
- an
.eslintrc.json-only project on ESLint 10.12.0 and 9.39.5, with and withoutESLINT_USE_FLAT_CONFIG=false @eslint/migrate-configon a config withoutenvand one withenv: { node: true }, run before and after installing the packages it asked for, and a hand-written flat config- eslint 10.12.0 with eslint-config-next 16.4.0 and next 16.4.0, linting a JSX file written to break rules from each plugin
- eslint 10.12.0 with eslint-plugin-react 7.37.5 installed directly, then with
--legacy-peer-deps, then with anoverridesentry
I only tested the rules those configs enable. A plugin that hasn’t declared ESLint 10 support could still have a rule that breaks on it.
The code is public, so you can run it yourself: eslint10 in nk-repro.
— N.K., end of entry No.056