Migrate to ESLint v10
ESLint v10.0.0 is a major release with several breaking changes. This guide walks you through upgrading from v9.x to v10.x, with real examples and actionable steps.ESLint v10 was released on February 6, 2026 and requires Node.js
^20.19.0 || ^22.13.0 || >=24.Quick Migration Checklist
Update Node.js
Ensure you’re running Node.js v20.19.0 or later:If your version is older, upgrade to at least Node.js v20.19.0.
Migrate Configuration
Remove any eslintrc files and ensure you’re using flat config (
eslint.config.js).Breaking Changes
Node.js Version Requirements
ESLint v10 requires:- Node.js
^20.19.0 - Node.js
^22.13.0 - Node.js
>=24
Configuration File Lookup
In v9, ESLint looked foreslint.config.js starting from your current working directory. In v10, it starts from each linted file’s directory and searches upward.
Before (v9 with CWD-based lookup):
ESLintrc Format Removed
ESLint v10 only supports the flat config format (eslint.config.js).
Old Format (.eslintrc.json):
.eslintrc.eslintrc.json.eslintrc.js.eslintrc.ymleslintConfiginpackage.jsonESLINT_USE_FLAT_CONFIGenvironment variable
JSX Reference Tracking
Enhancement: ESLint now correctly tracks JSX references in scope analysis.
no-unused-varswould reportCardas unused ❌- Removing the import wouldn’t trigger
no-undef❌
<Card>is correctly recognized as a reference toCard✅- Scope analysis works correctly for JSX ✅
- Remove workaround rules like
@eslint-react/jsx-uses-vars:
- Fix new linting errors that may appear in JSX files
eslint-env Comments Now Error
This will now fail:eslint-env comments and configure globals in eslint.config.js:
Updated eslint:recommended
Three new rules are enabled in
eslint:recommended.no-unassigned-vars- Disallow variables that are never assignedno-useless-assignment- Disallow assignments with no effectpreserve-caught-error- Require catch parameters to be used
API Changes for Plugin Developers
RuleTester Stricter Validation
This will now fail:Removed context Methods
Migration table:| Removed | Replacement |
|---|---|
context.getCwd() | context.cwd |
context.getFilename() | context.filename |
context.getPhysicalFilename() | context.physicalFilename |
context.getSourceCode() | context.sourceCode |
context.parserOptions | context.languageOptions |
Removed SourceCode Methods
| Removed | Replacement |
|---|---|
getTokenOrCommentBefore(node, skip) | getTokenBefore(node, { includeComments: true, skip }) |
getTokenOrCommentAfter(node, skip) | getTokenAfter(node, { includeComments: true, skip }) |
isSpaceBetweenTokens(first, second) | isSpaceBetween(first, second) |
getJSDocComment(node) | No replacement |
Dependency Updates
Jiti Version Requirement
If using TypeScript config files, ensure
jiti is at least v2.2.0.Minimatch v10
ESLint v10 uses minimatch v10, which supports POSIX character classes:Common Migration Issues
Error: 'v10_config_lookup_from_file' flag not recognized
Error: 'v10_config_lookup_from_file' flag not recognized
Solution: Remove the flag from your configuration. It’s now the default behavior.
Error: Configuration file not found
Error: Configuration file not found
Solution: Ensure you have
eslint.config.js (not .eslintrc) in your project root.Error: /* eslint-env */ comments not supported
Error: /* eslint-env */ comments not supported
Solution: Remove
eslint-env comments and configure globals in eslint.config.js:JSX components flagged as unused
JSX components flagged as unused
Solution: This shouldn’t happen in v10 (JSX tracking is fixed). If you see this, ensure you’ve removed workaround plugins like
@eslint-react/jsx-uses-vars.TypeError: context.getFilename is not a function
TypeError: context.getFilename is not a function
Solution: Update your rule to use
context.filename instead of context.getFilename():Testing Your Migration
Resources
Official Migration Guide
Complete official migration documentation
Configuration Guide
Learn about flat config format
Breaking Changes
Full list of breaking changes
CHANGELOG
Complete version history