
Highlights
ESLint v10.0.0 is a major release that includes several new features and breaking changes. Here are some of the most notable updates.
Installing
Because this is a major release, you may not automatically be upgraded by npm. To ensure you are using this version, run:
npm i eslint@10.0.0 --save-dev
Node.js < v20.19.0, v21.x, v23.x no longer supported
As of this post, Node.js v24.x is the LTS release, and as such we are dropping support for all versions of Node.js prior to v20.19.0 as well as v21.x and v23.x.
Migration Guide
As there are a lot of changes, we’ve created a migration guide describing the breaking changes in great detail along with the steps you should take to address them. We expect that most users should be able to upgrade without any build changes, but the migration guide should be a useful resource if you encounter problems.
New configuration file lookup algorithm
ESLint v10.0.0 locates eslint.config.* by starting from the directory of each linted file rather than the current working directory as was the case with ESLint v9.x. The new behavior allows for using multiple configuration files in the same run and can be particularly useful in monorepo setups.
In ESLint v9.x, this config lookup behavior could be enabled with the v10_config_lookup_from_file feature flag. In ESLint v10.0.0, this behavior is now the default and the v10_config_lookup_from_file flag has been removed.
Removed eslintrc functionality
As announced in Flat config rollout plans, the eslintrc config system has been completely removed in ESLint v10.0.0. Specifically, this means:
- The
ESLINT_USE_FLAT_CONFIGenvironment variable is no longer honored. - The CLI no longer supports eslintrc-specific arguments (
--no-eslintrc,--env,--resolve-plugins-relative-to,--rulesdir,--ignore-path). .eslintrc.*and.eslintignorefiles will no longer be honored./* eslint-env */comments are reported as errors.- The
loadESLint()function now always returns theESLintclass. - The
LinterconstructorconfigTypeargument can only be"flat"and will throw an error if"eslintrc"is passed. - The following
Lintereslintrc-specific methods are removed:defineParser()defineRule()defineRules()getRules()
- The following changes to the
/use-at-your-own-riskentrypoint:LegacyESLintis removedFileEnumeratoris removedshouldUseFlatConfig()function will always returntrue
JSX references are now tracked
ESLint v10.0.0 now tracks JSX references, enabling correct scope analysis of JSX elements.
Previously, JSX identifiers weren’t tracked as references, which could lead to incorrect results in rules relying on scope information. For example:
import { Card } from "./card.jsx";
export function createCard(name) {
return <Card name={name} />;
}
Prior to v10.0.0:
- False positives:
<Card>could be reported as “defined but never used” (no-unused-vars). - False negatives: Removing the import might not trigger an “undefined variable” error (
no-undef).
Starting with v10.0.0, <Card> is treated as a normal reference to the variable in scope. This eliminates confusing false positives/negatives, aligns JSX handling with developer expectations, and improves the linting experience in projects using JSX.
Espree and ESLint Scope now include types
Beginning with Espree v11.1.0 and ESLint Scope v9.1.0, these packages now contain built-in type definitions.
Previously, type definitions were provided by Definitely Typed packages @types/espree and @types/eslint-scope. There are several differences between the old and new type definitions, mostly bug fixes. If your code relies on types for the Espree and ESLint Scope packages, check if there are any updates needed.
Enhancements to RuleTester
Since its earliest days, ESLint has provided the RuleTester API to help plugin authors test their rules against custom test cases and configurations. This release introduces several enhancements to RuleTester to enforce more robust test definitions and improve debugging.
Assertion options
The RuleTester#run() method now supports assertion options, specifically requireMessage, requireLocation, and requireData, to let developers enforce stricter requirements in rule tests. These options enforce that every invalid test case explicitly checks violation messages, locations, and data, ensuring that a test fails if it doesn’t meet the requirements.
-
requireMessage- Ensures every test case includes a message check.
- Accepts:
true: Must use an array of objects forerrors, rather than a numeric count shorthand, to check the problems reported by a rule. Each object must include amessageormessageIdproperty as usual to check the message of a reported problem."message": Must check usingmessageonly."messageId": Must check usingmessageIdonly.
- Purpose: Prevents tests from passing without verifying the actual message.
-
requireLocation- Ensures every test case includes a location check.
- Accepts:
true - Requires
lineandcolumnin each object of theerrorsarray. endLineandendColumnare optional if the actual report doesn’t include them.- Purpose: Guarantees that tests validate the location of an error.
-
requireData- Ensures every test case includes a
datacheck. - Accepts:
true - When set to
true,RuleTesterwill require invalid test cases to include adataobject whenever amessageIdreferences a message with placeholders. This helps ensure that tests remain consistent with rule messages that rely on placeholder substitution.
- Ensures every test case includes a
Example Usage:
ruleTester.run("my-rule", rule, {
valid: [
{ code: "var foo = true;" }
],
invalid: [
{
code: "var invalidVariable = true;",
errors: [
{ message: "Unexpected invalid variable.", line: 1, column: 5 }
]
}
],
assertionOptions: {
requireMessage: true,
requireLocation: true
}
});
Improved location reporting for failing tests
RuleTester now decorates stack traces with information that makes it easier to locate failing test cases in your source code. For example, the test output will now include stack trace lines indicating the index of the failing test case in the invalid array and the file and line number where that test case is defined.
Note that these line numbers may not always be included, depending on how your tests are structured. When the lines cannot be determined precisely, the failing test index and the printed code snippet are still available to locate the test case.
countThis option in max-params rule
The max-params rule now supports the new countThis option, which supersedes the deprecated countVoidThis. With the setting countThis: "never", the rule will now ignore any this annotation in a function’s argument list when counting the number of parameters in a TypeScript function. For example:
function doSomething(this: SomeType, first: string, second: number) {
// ...
}
will be considered a function taking only 2 parameters.
color property in formatter context
When the --color or --no-color option is specified on the command line, ESLint sets an additional color property on the context object passed to a formatter (the second argument of the format() method). This property is true for --color and false for --no-color. Custom formatters can use this value to determine whether to apply color styling, based on the assumption that the terminal supports or does not support colors as indicated by the option.
Updated eslint:recommended
The eslint:recommended configuration is updated to include new rules that we feel are important.
Removed deprecated rule context members
The following rule context members are no longer available:
context.getCwd()- Usecontext.cwdinsteadcontext.getFilename()- Usecontext.filenameinsteadcontext.getPhysicalFilename()- Usecontext.physicalFilenameinsteadcontext.getSourceCode()- Usecontext.sourceCodeinsteadcontext.parserOptions- Usecontext.languageOptionsorcontext.languageOptions.parserOptionsinsteadcontext.parserPath- No replacement
Removed deprecated SourceCode methods
The following SourceCode methods are no longer available:
getTokenOrCommentBefore()- UsegetTokenBefore()with the{ includeComments: true }option insteadgetTokenOrCommentAfter()- UsegetTokenAfter()with the{ includeComments: true }option insteadisSpaceBetweenTokens()- UseisSpaceBetween()insteadgetJSDocComment()- No replacement
Program AST node range spans entire source text
Starting with ESLint v10.0.0, Program AST node’s range spans the entire source text. Previously, leading and trailing comments/whitespace were not included in the range.
Jiti < v2.2.0 no longer supported
ESLint v10.0.0 drops support for jiti versions prior to 2.2.0 when loading TypeScript configuration files due to known issues that can cause compatibility problems when configurations load certain plugins.
Breaking Changes
f9e54f4feat!: estimate rule-tester failure location (#20420) (ST-DDT)a176319feat!: replacechalkwithstyleTextand addcolortoResultsMeta(#20227) (루밀LuMir)c7046e6feat!: enable JSX reference tracking (#20152) (Pixel998)fa31a60feat!: addnameto configs (#20015) (Kirk Waiblinger)3383e7efix!: remove deprecatedSourceCodemethods (#20137) (Pixel998)501abd0feat!: update dependency minimatch to v10 (#20246) (renovate[bot])ca4d3b4fix!: stricter rule tester assertions for valid test cases (#20125) (唯然)96512a6fix!: Remove deprecated rule context methods (#20086) (Nicholas C. Zakas)c69fdacfeat!: remove eslintrc support (#20037) (Francesco Trotta)208b5ccfeat!: UseScopeManager#addGlobals()(#20132) (Milos Djermanovic)a2ee188fix!: adduniqueItems: trueinno-invalid-regexpoption (#20155) (Tanuj Kanti)a89059dfeat!: Program range span entire source text (#20133) (Pixel998)39a6424fix!: assert ‘text’ is a string across all RuleFixer methods (#20082) (Pixel998)f28fbf8fix!: Deprecate"always"and"as-needed"options of theradixrule (#20223) (Milos Djermanovic)aa3fb2bfix!: tightenfunc-namesschema (#20119) (Pixel998)f6c0ed0feat!: reporteslint-envcomments as errors (#20128) (Francesco Trotta)4bf739ffix!: remove deprecatedLintMessage#nodeTypeandTestCaseError#type(#20096) (Pixel998)523c076feat!: drop support for jiti < 2.2.0 (#20016) (michael faith)454a292feat!: updateeslint:recommendedconfiguration (#20210) (Pixel998)4f880eefeat!: removev10_*and inactiveunstable_*flags (#20225) (sethamus)f18115cfeat!:no-shadow-restricted-namesreportglobalThisby default (#20027) (sethamus)c6358c3feat!: Require Node.js^20.19.0 || ^22.13.0 || >=24(#20160) (Milos Djermanovic)
Features
bff9091feat: handleArray.fromAsyncinarray-callback-return(#20457) (Francesco Trotta)290c594feat: addselftono-implied-evalrule (#20468) (sethamus)43677defeat: fix handling of function and class expression names inno-shadow(#20432) (Milos Djermanovic)f0cafe5feat: rule tester add assertion optionrequireData(#20409) (fnx)f7ab693feat: output RuleTester test case failure index (#19976) (ST-DDT)7cbcbf9feat: addcountThisoption tomax-params(#20236) (Gerkin)f148a5efeat: add error assertion options (#20247) (ST-DDT)09e6654feat: update error loc ofrequire-yieldandno-useless-constructor(#20267) (Tanuj Kanti)
Bug Fixes
436b82ffix: update eslint (#20473) (renovate[bot])1d29d22fix: detect defaultthisbinding inArray.fromAsynccallbacks (#20456) (Francesco Trotta)727451efix: fix regression of global mode report range instrictrule (#20462) (ntnyq)e80485ffix: remove fakeFlatESLintandLegacyESLintexports (#20460) (Francesco Trotta)9eeff3bfix: update esquery (#20423) (cryptnix)b34b938fix: useError.prepareStackTraceto estimate failing test location (#20436) (Francesco Trotta)51aab53fix: update eslint (#20443) (renovate[bot])23490b2fix: handle space before colon inRuleTesterlocation estimation (#20433) (Francesco Trotta)f244dbffix: useMessagePlaceholderDatatype from@eslint/core(#20348) (루밀LuMir)d186f8cfix: update eslint (#20427) (renovate[bot])2332262fix: error location should not modify error message in RuleTester (#20421) (Milos Djermanovic)ab99b21fix: ensurefilenameis passed as third argument toverifyAndFix()(#20405) (루밀LuMir)8a60f3bfix: removeecmaVersionandsourceTypefromParserOptionstype (#20415) (Pixel998)eafd727fix: removeTDZscope type (#20231) (jaymarvelz)39d1f51fix: correctScopetypings (#20404) (sethamus)2bd0f13fix: updateverifyandverifyAndFixtypes (#20384) (Francesco Trotta)ba6ebfafix: correct typings forloadESLint()andshouldUseFlatConfig()(#20393) (루밀LuMir)e7673aefix: correct RuleTester typings (#20105) (Pixel998)53e9522fix: strict removed formatters check (#20241) (ntnyq)b017f09fix: correctno-restricted-importmessages (#20374) (Francesco Trotta)
Documentation
e978ddadocs: Update README (GitHub Actions Bot)4cecf83docs: Update README (GitHub Actions Bot)c79f0abdocs: Update README (GitHub Actions Bot)773c052docs: Update README (GitHub Actions Bot)f2962e4docs: documentmeta.docs.frozenproperty (#20475) (Pixel998)8e94f58docs: fix broken anchor links from gerund heading updates (#20449) (Copilot)1495654docs: Update README (GitHub Actions Bot)0b8ed5cdocs: document support for:isselector alias (#20454) (sethamus)1c4b33fdocs: Document policies about ESM-only dependencies (#20448) (Milos Djermanovic)3e5d38cdocs: add missing indentation space in rule example (#20446) (fnx)63a0c7cdocs: Update README (GitHub Actions Bot)65ed0c9docs: Update README (GitHub Actions Bot)b0e4717docs: [no-await-in-loop] Expand inapplicability (#20363) (Niklas Hambüchen)fca421fdocs: Update README (GitHub Actions Bot)d925c54docs: update config syntax inno-lone-blocks(#20413) (Pixel998)7d5c95fdocs: remove redundantsourceType: "module"from rule examples (#20412) (Pixel998)02e7e71docs: correct.mtsglob pattern in files with extensions example (#20403) (Ali Essalihi)264b981docs: Update README (GitHub Actions Bot)5a4324fdocs: clarify"local"option ofno-unused-vars(#20385) (Milos Djermanovic)e593aa0docs: improve clarity, grammar, and wording in documentation site README (#20370) (Aditya)3f5062edocs: Add messages property to rule meta documentation (#20361) (Sabya Sachi)9e5a5c2docs: removeExamplesheadings from rule docs (#20364) (Milos Djermanovic)194f488docs: Update README (GitHub Actions Bot)0f5a94adocs: [class-methods-use-this] explain purpose of rule (#20008) (Kirk Waiblinger)df5566fdocs: add Options section to all rule docs (#20296) (sethamus)adf7a2bdocs: no-unsafe-finally note for generator functions (#20330) (Tom Pereira)ef7028cdocs: Update README (GitHub Actions Bot)fbae5d1docs: consistently use “v10.0.0” in migration guide (#20328) (Pixel998)778aa2ddocs: ignoring default file patterns (#20312) (Tanuj Kanti)4b5dbcddocs: reorder v10 migration guide (#20315) (Milos Djermanovic)5d84a73docs: Update README (GitHub Actions Bot)37c8863docs: fix incorrect anchor link in v10 migration guide (#20299) (Pixel998)077ff02docs: add migrate-to-10.0.0 doc (#20143) (唯然)3822e1bdocs: Update README (GitHub Actions Bot)
Build Related
9f08712Build: changelog update for 10.0.0-rc.2 (Jenkins)1e2c449Build: changelog update for 10.0.0-rc.1 (Jenkins)c4c72a8Build: changelog update for 10.0.0-rc.0 (Jenkins)7e4daf9Build: changelog update for 10.0.0-beta.0 (Jenkins)a126a2abuild: add .scss files entry to knip (#20389) (Francesco Trotta)f5c0193Build: changelog update for 10.0.0-alpha.1 (Jenkins)165326fBuild: changelog update for 10.0.0-alpha.0 (Jenkins)
Chores
1ece282chore: ignore/docs/v9.xin link checker (#20452) (Milos Djermanovic)034e139ci: add type integration test for@html-eslint/eslint-plugin(#20345) (sethamus)f3fbc2fchore: set@eslint/jsversion to 10.0.0 to skip releasing it (#20466) (Milos Djermanovic)afc0681chore: remove scopeManager.addGlobals patch for typescript-eslint parser (#20461) (fnx)3e5a173refactor: use types from@eslint/plugin-kit(#20435) (Pixel998)11644b1ci: rename workflows (#20463) (Milos Djermanovic)2d14173chore: fix typos in docs and comments (#20458) (o-m12a)6742f92test: add endLine/endColumn to invalid test case in no-alert (#20441) (경하)3e22c82test: add missing location data to no-template-curly-in-string tests (#20440) (Haeun Kim)b4b3127chore: package.json update for @eslint/js release (Jenkins)f658419refactor: removerawparser option from JS language (#20416) (Pixel998)2c3efb7chore: removecategoryfrom type test fixtures (#20417) (Pixel998)36193fdchore: removecategoryfrom formatter test fixtures (#20418) (Pixel998)e8d203bchore: add JSX language tag validation tocheck-rule-examples(#20414) (Pixel998)bc465a1chore: pin dependencies (#20397) (renovate[bot])703f0f5test: replace deprecated rules inlintertests (#20406) (루밀LuMir)ba71baatest: enablestrictmode in type tests (#20398) (루밀LuMir)f9c4968refactor: removelib/linter/rules.js(#20399) (Francesco Trotta)6f1c48echore: updates for v9.39.2 release (Jenkins)54bf0a3ci: create package manager test (#20392) (루밀LuMir)3115021refactor: simplify JSDoc comment detection logic (#20360) (Pixel998)4345b17chore: update@eslint-community/regexppto4.12.2(#20366) (루밀LuMir)772c9eechore: update dependency @eslint/eslintrc to ^3.3.3 (#20359) (renovate[bot])0b14059chore: package.json update for @eslint/js release (Jenkins)d6e7bf3ci: bump actions/checkout from 5 to 6 (#20350) (dependabot[bot])139d456chore: require mandatory headers in rule docs (#20347) (Milos Djermanovic)3b0289cchore: remove unused.eslintignoreand test fixtures (#20316) (Pixel998)a463e7bchore: update dependency js-yaml to v4 [security] (#20319) (renovate[bot])ebfe905chore: remove redundant rules from eslint-config-eslint (#20327) (Milos Djermanovic)88dfdb2test: add regression tests for message placeholder interpolation (#20318) (fnx)6ed0f75chore: skip type checking ineslint-config-eslint(#20323) (Francesco Trotta)1e2cad5chore: package.json update for @eslint/js release (Jenkins)9da2679chore: update@eslint/*dependencies (#20321) (Milos Djermanovic)0439794refactor: use types from @eslint/core (#20235) (jaymarvelz)cb51ec2test: cleanupSourceCode#traversetests (#20289) (Milos Djermanovic)897a347chore: remove restriction fortypein rule tests (#20305) (Pixel998)d972098chore: ignore prettier updates in renovate to keep in sync with trunk (#20304) (Pixel998)a086359chore: remove redundantfast-globdev-dependency (#20301) (루밀LuMir)564b302chore: installprettieras a dev dependency (#20302) (michael faith)8257b57refactor: correct regex foreslint-plugin/report-message-format(#20300) (루밀LuMir)e251671refactor: extract assertions in RuleTester (#20135) (唯然)2e7f25echore: addlegacy-peer-depsto.npmrc(#20281) (Milos Djermanovic)39c638achore: update eslint-config-eslint dependencies for v10 prereleases (#20278) (Milos Djermanovic)8533b3fchore: update dependency @eslint/json to ^0.14.0 (#20288) (renovate[bot])796ddf6chore: update dependency @eslint/js to ^9.39.1 (#20285) (renovate[bot])

