ESLint v9.0.0 released

We just pushed ESLint v9.0.0, which is a major release upgrade of ESLint. This release adds some new features and fixes several bugs found in the previous release. This release also has some breaking changes, so please read the following closely.

Highlights

This is a summary of the significant changes, both breaking and non-breaking, you need to know about when upgrading from ESLint v8.x to ESLint v9.0.0.

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 [email protected] --save-dev

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.

Node.js < v18.18.0, v19 no longer supported

As of this post, Node.js v20.x is the LTS release, and as such we are dropping support for all versions of Node.js prior to v18.18.0 as well as v19.x.

Flat config is now the default and has some changes

Flat config is now the default configuration format for ESLint and eslintrc is officially deprecated. To continue using a eslintrc configuration file, you’ll need to set the ESLINT_USE_FLAT_CONFIG environment variable to false.

This change affects users, plugin developers, and integrators as many aspects of ESLint had to change to make this happen. Please see our previous blog post for more details.

This release also introduces the config inspector, which can be launched on the command line using --inspect-config.

Removed all formatters except stylish, html, json, and json-with-meta

The following formatters have been removed:

  • checkstyle
  • compact
  • jslint-xml
  • junit
  • tap
  • unix
  • visualstudio

If you are using these formatters currently, you’ll need to install the standalone packages for use with ESLint v9.0.0.

Removed valid-jsdoc and require-jsdoc rules

We have removed valid-jsdoc and require-jsdoc. We recommend using the eslint-plugin-jsdoc plugin instead.

Removed deprecated methods on context and SourceCode

As we announced in September, we have removed a lot of deprecated methods from context and replaced them with methods on SourceCode.

Updated eslint:recommended

The eslint:recommended configuration is updated to include new rules that we feel are important, and to remove deprecated and less important rules.

New rule: no-useless-assignment

ESLint v9.0.0 introduces a new rule, no-useless-assignment, that is designed to catch situations where you’ve assigned a value to a variable and that value is never used. For example:

let id = 1234;      // 1234 is never used
id = calculateId();

Updates to existing rules

  • The complexity rule now also takes into account optional chaining and default values in destructuring patterns and parameters.
  • The no-fallthrough rule has a new option reportUnusedFallthroughComment.
  • The no-inner-declarations rule has a new default behavior. In v8.x, the rule would flag any functions defined inside of blocks as errors because this behavior was undefined in early versions of JavaScript. As of ES 2015, block-scoped function declarations are well-defined and so we changed the default behavior to not warn on block-scoped functions.
  • The no-misleading-character-class rule now highlights the offending characters in a regular expression rather than the entire regular expression.
  • The no-restricted-imports rule changed the behavior of paths. In v8.x, if multiple entries in the paths array of your configuration for The no-restricted-imports rule had the same name property, only the last one would apply. In v9.0.0, all entries apply, allowing for specifying different error messages for different imported names.
  • The no-restricted-imports rule has new options allowImportNames and allowImportNamePattern.
  • The no-unused-vars rule varsIgnorePattern option no longer applies to caught error variables.
  • The no-unused-vars rule has a new default value for the caughtErrors option (changed from "none" to "all").
  • The no-unused-vars rule has a new option ignoreClassWithStaticInitBlock.
  • The no-unused-vars rule has a new option reportUsedIgnorePattern.
  • The no-useless-computed-key rule has a new default value for the enforceForClassMembers option (changed from false to true). This is intended to help avoiding misleading comments that can occur as a result of refactoring. When this option is set to true, the rule will prohibit a fallthrough comment if a case can never fallthrough.

New API loadESLint()

ESLint now exports a new function loadESLint() from its main entry point. Integrations can use this function to get either the ESLint class (former FlatESLint class) or the LegacyESLint class (former ESLint class) and thus easily swap between flat config and eslintrc APIs.

Changes to how you write rules

We’ve made multiple changes to help prevent errors in rules:

  1. Function-style rules will stop working in v9.0.0. Function-style rules are rules created by exporting a function from a file rather than exporting an object with a create() method.
  2. When a rule doesn’t have meta.schema specified, a default schema of [] will be applied. This means that rules without a schema will be assumed to have no options, which in turn means that validation will fail if options are provided.

Stricter RuleTester validations

This release adds more checks in RuleTester:

  • Messages cannot have unsubstituted placeholders.
  • Suggestions must change the code.
  • Suggestion messages must be unique for the same lint problem.
  • Suggestions must generate valid syntax.
  • Test case output must be different from code.
  • Test error objects must specify message or messageId.
  • Test error object must specify suggestions if the actual error provides suggestions.
  • Test suggestion objects must specify desc or messageId.
  • Test suggestion objects must specify output.
  • filename and only properties of test objects must be of the expected type (string and boolean, respectively).
  • Duplicate tests cause an error.

The --output-file flag now guarantees a file is output

The --output-file CLI flag is designed to output the results of the ESLint run to specified file. Prior to this release, no file would be output if linting passed with no errors or warnings. In v9.0.0, an empty file will be output when linting passes without any errors or warnings.

Better scope analysis

In v9.0.0, we updated the behavior of eslint-scope to fix a couple of longstanding bugs:

  1. Previously, ESLint would treat ("use strict") as a strict mode directive even though it is not. We fixed the behavior so only valid strict mode directives are honored.
  2. The containing scope of a class extends clause was incorrectly set to be the scope containing the class when it should have been the class scope itself. This has been fixed.

CodePath#currentSegments removed

As announced in our previous post, CodePath#currentSegments has been removed from the rules API. Please refer to the post for more details.

Precalculated Code Paths

ESLint v9.0.0 now precalculates code path information before the traversal used by rules. As a result, the code path information is now complete regardless of where it is accessed inside of a rule.

Multiple /* eslint */ comments for the same rule are now disallowed

In ESLint v8.x, if the file being linted contained multiple /* eslint */ configuration comments for the same rule, the last one would be applied, while the others would be silently ignored.

In ESLint v9.0.0, the first one is applied, while the others are reported as lint errors.

--quiet option is more performant

The --quiet option hides all warnings in the ESLint console. In v9.0.0, we are making a performance improvement by also not executing any rules set to "warn".

Running eslint with no file arguments

If you are using flat config and you don’t pass any file arguments to the CLI, the CLI will default to linting the current directory, which means you can type npx eslint and it will just work. (Doing the same with an eslintrc config file will result in an error.)

Unused disable directives cause warnings by default

ESLint has long been able to flag unused disable directives. In this release, we’ve enabled warnings for unused disable directives by default. You can modify this value in your config file with linterOptions.reportUnusedDisableDirectives or on the command line using --report-unused-disable-directives-severity.

Performance statistics available in formatters via --stats

The information from the rule profiler is now available inside of formatters when the --stats flag is used in the CLI. This allows anyone to create custom visualizations of the performance information that ESLint tracks.

Breaking Changes

Features

Bug Fixes

Documentation

  • e151050 docs: update get-started to the new @eslint/create-config (#18217) (唯然)
  • 94178ad docs: mention about name field in flat config (#18252) (Anthony Fu)
  • 1765c24 docs: add Troubleshooting page (#18181) (Josh Goldberg ✨)
  • 96607d0 docs: version selectors synchronization (#18260) (Milos Djermanovic)
  • 651ec91 docs: remove /* eslint-env */ comments from rule examples (#18249) (Milos Djermanovic)
  • 950c4f1 docs: Update README (GitHub Actions Bot)
  • 12f5746 docs: add info about dot files and dir in flat config (#18239) (Tanuj Kanti)
  • b93f408 docs: update shared settings example (#18251) (Tanuj Kanti)
  • 26384d3 docs: fix ecmaVersion in one example, add checks (#18241) (Milos Djermanovic)
  • 7747097 docs: Update PR review process (#18233) (Nicholas C. Zakas)
  • b07d427 docs: fix typo (#18246) (Kirill Gavrilov)
  • 778082d docs: add Glossary page (#18187) (Josh Goldberg ✨)
  • 239a7e2 docs: Clarify the description of sort-imports options (#18198) (gyeongwoo park)
  • 4769c86 docs: fix incorrect example in no-lone-blocks (#18215) (Tanuj Kanti)
  • 5251327 docs: Update README (GitHub Actions Bot)
  • 1dc8618 docs: Update README (GitHub Actions Bot)
  • ba1c1bb docs: Update README (GitHub Actions Bot)
  • 337cdf9 docs: Explain limitations of RuleTester fix testing (#18175) (Nicholas C. Zakas)
  • c7abd89 docs: Explain Node.js version support (#18176) (Nicholas C. Zakas)
  • d961eeb docs: show red underlines in examples in rules docs (#18041) (Yosuke Ota)
  • 558274a docs: Update README (GitHub Actions Bot)
  • 2908b9b docs: Update release documentation (#18174) (Nicholas C. Zakas)
  • 1f1260e docs: replace HackerOne link with GitHub advisory (#18165) (Francesco Trotta)
  • e5ef3cd docs: add inline cases condition in no-fallthrough (#18158) (Tanuj Kanti)
  • 450d0f0 docs: fix ignore option docs (#18154) (Francesco Trotta)
  • 5fe095c docs: show v8.57.0 as latest version in dropdown (#18142) (Milos Djermanovic)
  • 7db5bb2 docs: Show prerelease version in dropdown (#18135) (Nicholas C. Zakas)
  • 73a5f06 docs: Update README (GitHub Actions Bot)
  • f95cd27 docs: Disallow multiple rule configuration comments in the same example (#18116) (Milos Djermanovic)
  • d8068ec docs: Update link for schema examples (#18112) (Svetlana)
  • f1c7e6f docs: Switch to Ethical Ads (#18090) (Strek)
  • 15c143f docs: JS Foundation -> OpenJS Foundation in PR template (#18092) (Nicholas C. Zakas)
  • 6ea339e docs: add stricter rule test validations to v9 migration guide (#18085) (Milos Djermanovic)
  • 3c816f1 docs: use relative link from CLI to core concepts (#18083) (Milos Djermanovic)
  • 9458735 docs: fix malformed eslint config comments in rule examples (#18078) (Francesco Trotta)
  • 07a1ada docs: link from --fix CLI doc to the relevant core concept (#18080) (Bryan Mishkin)
  • b844324 docs: Update team responsibilities (#18048) (Nicholas C. Zakas)
  • aadfb60 docs: document languageOptions and other v9 changes for context (#18074) (fnx)
  • 857e242 docs: tweak explanation for meta.docs rule properties (#18057) (Bryan Mishkin)
  • 10485e8 docs: recommend messageId over message for reporting rule violations (#18050) (Bryan Mishkin)
  • 98b5ab4 docs: Update README (GitHub Actions Bot)
  • 505fbf4 docs: update no-restricted-imports rule (#18015) (Tanuj Kanti)
  • c25b4af docs: Update README (GitHub Actions Bot)
  • 33d1ab0 docs: add more examples to flat config ignores docs (#18020) (Milos Djermanovic)
  • e6eebca docs: Update sort-keys options properties count (#18025) (LB (Ben Johnston))
  • 1fedfd2 docs: Improve flat config ignores docs (#17997) (Nicholas C. Zakas)
  • 38b9b06 docs: update valid-typeof rule (#18001) (Tanuj Kanti)
  • b4abfea docs: Update note about ECMAScript support (#17991) (Francesco Trotta)
  • 6788873 docs: Update release blog post template (#17994) (Nicholas C. Zakas)
  • 1f37442 docs: Add sections on non-npm plugin configuration (#17984) (Nicholas C. Zakas)
  • 96307da docs: migration guide entry for no-inner-declarations (#17977) (Tanuj Kanti)
  • 40be60e docs: Update README (GitHub Actions Bot)
  • d31c180 docs: fix number of code-path events on custom rules page (#17969) (Richard Hunter)
  • 1529ab2 docs: reorder entries in v9 migration guide (#17967) (Milos Djermanovic)
  • 9507525 docs: Explain how to combine configs (#17947) (Nicholas C. Zakas)
  • 7c78576 docs: Add more removed context methods to migrate to v9 guide (#17951) (Milos Djermanovic)
  • 3a877d6 docs: Update removed CLI flags migration (#17939) (Nicholas C. Zakas)
  • 4a9cd1e docs: Update Linter API for v9 (#17937) (Milos Djermanovic)
  • 2a8eea8 docs: update docs for v9.0.0-alpha.0 (#17929) (Milos Djermanovic)
  • 7f0ba51 docs: show NEXT in version selectors (#17911) (Milos Djermanovic)
  • 0a7911e docs: add flat config default to v9 migration guide (#17927) (Milos Djermanovic)
  • 94f8065 docs: Add CLI updates to migrate to v9 guide (#17924) (Nicholas C. Zakas)
  • 16187f2 docs: Add exported and string config notes to migrate to v9 guide (#17926) (Nicholas C. Zakas)
  • 3ae50cc docs: Add RuleTester changes to migrate to v9 guide (#17923) (Nicholas C. Zakas)
  • 0831b58 docs: add rule changes to v9 migration guide (#17925) (Milos Djermanovic)
  • 037abfc docs: update API docs (#17919) (Milos Djermanovic)
  • afc3c03 docs: add function-style and meta.schema changes to v9 migration guide (#17912) (Milos Djermanovic)
  • 1da0723 docs: update eslint:recommended section in Migrate to v9.x (#17908) (Milos Djermanovic)
  • f55881f docs: remove configuration-files-new.md (#17907) (Milos Djermanovic)
  • 63ae191 docs: Migrate to v9.0.0 (#17905) (Nicholas C. Zakas)
  • e708496 docs: Switch to flat config by default (#17840) (Nicholas C. Zakas)
  • fdf0424 docs: Update Create a Plugin for flat config (#17826) (Nicholas C. Zakas)
  • e6a91bd docs: Switch shareable config docs to use flat config (#17827) (Nicholas C. Zakas)
  • 3831fb7 docs: updated examples of max-lines rule (#17898) (Tanuj Kanti)
  • cd1ac20 docs: Update README (GitHub Actions Bot)
  • 26010c2 Build: changelog update for 9.0.0-rc.0 (Jenkins)
  • b91f9dc build: fix TypeError in prism-eslint-hooks.js (#18209) (Francesco Trotta)
  • d7ec0d1 Build: changelog update for 9.0.0-beta.2 (Jenkins)
  • fd9c0a9 Build: changelog update for 9.0.0-beta.1 (Jenkins)
  • c9f2f33 build: changelog update for 8.57.0 (#18144) (Milos Djermanovic)
  • 1bbc495 Build: changelog update for 9.0.0-beta.0 (Jenkins)
  • 96f8877 Build: changelog update for 9.0.0-alpha.2 (Jenkins)
  • 52d5e7a Build: changelog update for 9.0.0-alpha.1 (Jenkins)
  • c2bf27d build: update docs files when publishing prereleases (#17940) (Milos Djermanovic)
  • e91d85d Build: changelog update for 9.0.0-alpha.0 (Jenkins)

Chores

The latest ESLint news, case studies, tutorials, and resources.

ESLint v9.34.0 released
1 min read

ESLint v9.34.0 released

We just pushed ESLint v9.34.0, which is a minor release upgrade of ESLint. This release adds some new features and fixes several bugs found in the previous release.

ESLint v9.33.0 released
2 min read

ESLint v9.33.0 released

We just pushed ESLint v9.33.0, which is a minor release upgrade of ESLint. This release adds some new features and fixes several bugs found in the previous release.