ESLint v9.0.0-alpha.1 released

We just pushed ESLint v9.0.0-alpha.1, 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.


This is a summary of the major changes you need to know about for this version of ESLint.


Since this is a pre-release version, you will not automatically be upgraded by npm. You must specify the next tag when installing:

npm i eslint@next --save-dev

You can also specify the version directly:

npm i eslint@9.0.0-alpha.1 --save-dev

Migration Guide

As there are a lot of changes, we’ve created a migration guide describing the 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.

no-inner-declarations new default behavior

In v8.x, no-inner-declarations 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.

no-misleading-character-class now highlights the offending characters

In v8.x, the no-misleading-character-class rule would highlight an entire regular expression if it contained a misleading character class. In v9.0.0, this rule now highlights just the offending characters to help you more easily find errors.

no-unused-vars varsIgnorePattern option change

The varsIgnorePattern option of no-unused-vars was incorrectly applied to caught error variables in catch conditions. In v9.0.0, varsIgnorePattern no longer applies to caught error variables.

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();

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.

Breaking Changes

  • 701f1af feat!: no-inner-declaration new default behaviour and option (#17885) (Tanuj Kanti)
  • bde5105 fix!: handle --output-file for empty output when saving to disk (#17957) (Nitin Kumar)
  • 07107a5 fix!: upgrade eslint-scope@8.0.0 (#17942) (Milos Djermanovic)
  • 3ee0f6c fix!: no-unused-vars varsIgnorePattern behavior with catch arguments (#17932) (Tanuj Kanti)
  • 51f8bc8 fix!: configuration comments with just severity should retain options (#17945) (Milos Djermanovic)
  • d191bdd feat!: Remove CodePath#currentSegments (#17936) (Milos Djermanovic)


Bug Fixes


  • 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)
  • c2bf27d build: update docs files when publishing prereleases (#17940) (Milos Djermanovic)


  • c5e50ee chore: package.json update for @eslint/js release (Jenkins)
  • 1bf2520 chore: Split Docs CI from core CI (#17897) (Nicholas C. Zakas)
  • 320787e chore: delete relative-module-resolver.js (#17981) (Francesco Trotta)
  • 4926f33 refactor: use Object.hasOwn() (#17948) (Milos Djermanovic)
  • df200e1 refactor: use to get last elements (#17949) (Milos Djermanovic)
  • 750b8df chore: update dependency glob to v10 (#17917) (renovate[bot])
  • 74794f5 chore: removed unused eslintrc modules (#17938) (Milos Djermanovic)
  • 10ed29c chore: remove unused dependency rimraf (#17934) (Francesco Trotta)
  • 903ee60 ci: use --force flag when installing eslint (#17921) (Milos Djermanovic)

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

ESLint v9.5.0 released
2 min read

ESLint v9.5.0 released

We just pushed ESLint v9.5.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.4.0 released
1 min read

ESLint v9.4.0 released

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