Skip to main content

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

1

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.
2

Update ESLint

Update ESLint to v10.x:
3

Migrate Configuration

Remove any eslintrc files and ensure you’re using flat config (eslint.config.js).
4

Remove Feature Flags

Remove the v10_config_lookup_from_file flag from your configuration:
5

Test Your Configuration

Run ESLint to verify everything works:

Breaking Changes

Node.js Version Requirements

Breaking Change: ESLint v10 drops support for Node.js versions < v20.19, v21, and v23.
ESLint v10 requires:
  • Node.js ^20.19.0
  • Node.js ^22.13.0
  • Node.js >=24
Migration:
If you cannot upgrade Node.js immediately, continue using ESLint v9.x until you can upgrade.

Configuration File Lookup

Breaking Change: Config file lookup now starts from the linted file’s directory, not the current working directory.
In v9, ESLint looked for eslint.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):
After (v10 with file-based lookup):
Migration: If you relied on the old behavior, explicitly specify your config file:

ESLintrc Format Removed

Breaking Change: The legacy .eslintrc configuration format is no longer supported.
ESLint v10 only supports the flat config format (eslint.config.js). Old Format (.eslintrc.json):
New Format (eslint.config.js):
Remove These:
  • .eslintrc
  • .eslintrc.json
  • .eslintrc.js
  • .eslintrc.yml
  • eslintConfig in package.json
  • ESLINT_USE_FLAT_CONFIG environment variable
See the Configuration Migration Guide for detailed conversion steps.

JSX Reference Tracking

Enhancement: ESLint now correctly tracks JSX references in scope analysis.
Previously, ESLint didn’t recognize JSX identifiers as references: Example:
Before v10:
  • no-unused-vars would report Card as unused ❌
  • Removing the import wouldn’t trigger no-undef
After v10:
  • <Card> is correctly recognized as a reference to Card
  • Scope analysis works correctly for JSX ✅
Migration:
  1. Remove workaround rules like @eslint-react/jsx-uses-vars:
  1. Fix new linting errors that may appear in JSX files

eslint-env Comments Now Error

Breaking Change: /* eslint-env */ comments now cause linting errors.
This will now fail:
Error message:
Migration: Remove eslint-env comments and configure globals in eslint.config.js:

Updated eslint:recommended

Three new rules are enabled in eslint:recommended.
New rules in v10:
  • no-unassigned-vars - Disallow variables that are never assigned
  • no-useless-assignment - Disallow assignments with no effect
  • preserve-caught-error - Require catch parameters to be used
Example violations:
To disable:

API Changes for Plugin Developers

RuleTester Stricter Validation

Valid test cases cannot have errors or output properties.
This will now fail:
Correct usage:

Removed context Methods

Deprecated context methods have been removed.
Migration table: Example migration:
Use the eslint-transforms utility to automate this migration:

Removed SourceCode Methods

Deprecated SourceCode methods have been removed.
Example:

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

Solution: Remove the flag from your configuration. It’s now the default behavior.
Solution: Ensure you have eslint.config.js (not .eslintrc) in your project root.
Solution: Remove eslint-env comments and configure globals in eslint.config.js:
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.
Solution: Update your rule to use context.filename instead of context.getFilename():

Testing Your Migration

1

Run ESLint

2

Check for new errors

Review any new errors from eslint:recommended rules.
3

Test in CI/CD

Ensure your CI/CD pipeline uses Node.js v20.19+ and ESLint v10.
4

Update editor integrations

Restart your editor to pick up the new ESLint version.

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

Getting Help

If you encounter issues during migration: