ESLint v9.23.0 released

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

Highlights

TypeScript Syntax Support in Core Rules

ESLint v9.23.0 introduces full TypeScript syntax support for three core rules. These rules are:

These rules can now be used to lint TypeScript files as well as regular JavaScript. To lint TypeScript code, be sure to use @typescript-eslint/parser, or another compatible parser. You can define the parser and the rules in your config file like this:

import { defineConfig } from "eslint/config";
import tsParser from "@typescript-eslint/parser";

export default defineConfig([
    {
        files: ["**/*.ts"],
        languageOptions: {
            parser: tsParser,
        },
        rules: {
            "class-methods-use-this": "error",
            "default-param-last": "error",
            "no-useless-constructor": "error",
        },
    },
]);

ESLint is actively working to add TypeScript syntax support to other core rules. Expect more updates soon.

Conflicting Autofix Detection

When running ESLint with the —fix option, some problems can be fixed automatically. However, what happens when two rules have differing opinions on how a specific part of code should be fixed?

The result is a fixed code that fails to satisfy either rule, and that will still contain problems based on your configuration.

For instance, consider this configuration:

import { defineConfig } from "eslint/config";
import stylistic from "@stylistic/eslint-plugin";
import stylisticJs from "@stylistic/eslint-plugin-js";

export default defineConfig([
    {
        plugins: {
            "@stylistic": stylistic,
            "@stylistic/js": stylisticJs,
        },
        rules: {
            "@stylistic/semi": ["error", "never"],
            "@stylistic/js/semi": ["error", "always"],
        },
    },
]);

In the above configuration, the rule @stylistic/semi is set to never allow semicolons at the end of a statement, but the rule @stylistic/js/semi always requires them. Obviously, it isn’t possible fix the code in a way that a statement fits both constraints.

In previous ESLint versions, the only indications for conflicting fixes in a file was the fact that the fixed code would still contain fixable errors. This was surprising to many users, as the cause for the behavior was often unclear.

ESLint v9.23.0 detects when two rules produce conflicting fixes and emits a warning:

ESLintCircularFixesWarning: Circular fixes detected while fixing path/to/file. It is likely that you have conflicting rules in your configuration.

We also provide instructions to fix the config.

Automatic Lookup for Configs with “flat/” Prefix

An interesting new feature for plugin developers is ESLint’s ability to detect a legacy config specified by its name with the extends property, and fall back to use a config with a similar name with the “flat/” prefix. This simplifies things for plugins that need to maintain similar configs for ESLint v9 and for previous versions, and that cannot change their naming conventions for backwards compatibility. See the documentation for further information.

Features

Bug Fixes

Documentation

  • 5405939 docs: show red underlines in TypeScript examples in rules docs (#19547) (Milos Djermanovic)
  • 48b53d6 docs: replace var with const in examples (#19539) (Nitin Kumar)
  • c39d7db docs: Update README (GitHub Actions Bot)
  • a4f8760 docs: revert accidental changes (#19542) (Francesco Trotta)
  • 280128f docs: add copy button (#19512) (xbinaryx)
  • cd83eaa docs: replace var with const in examples (#19530) (Nitin Kumar)
  • 7ff0cde docs: Update README (GitHub Actions Bot)
  • 996cfb9 docs: migrate sass to module system (#19518) (xbinaryx)
  • 17cb958 docs: replace var with let and const in rule examples (#19515) (Tanuj Kanti)
  • 83e24f5 docs: Replace var with let or const (#19511) (Jenna Toff)
  • a59d0c0 docs: Update docs for defineConfig (#19505) (Nicholas C. Zakas)
  • fe92927 docs: require-unicode-regexp add note for i flag and \w (#19510) (Chaemin-Lim)
  • 2357edd build: exclude autogenerated files from Prettier formatting (#19548) (Francesco Trotta)

Chores

  • 0ac8ea4 chore: update dependencies for v9.23.0 release (#19554) (Francesco Trotta)
  • 20591c4 chore: package.json update for @eslint/js release (Jenkins)
  • 901344f chore: update dependency @eslint/json to ^0.11.0 (#19552) (renovate[bot])
  • 5228383 chore: fix update-readme formatting (#19544) (Milos Djermanovic)
  • 5439525 chore: format JSON files in Trunk (#19541) (Francesco Trotta)
  • 75adc99 chore: enabled Prettier in Trunk (#19354) (Josh Goldberg ✨)
  • 2395168 chore: added .git-blame-ignore-revs for Prettier via trunk fmt (#19538) (Josh Goldberg ✨)
  • 129882d chore: formatted files with Prettier via trunk fmt (#19355) (Josh Goldberg ✨)
  • 1738dbc chore: temporarily disable prettier in trunk (#19537) (Josh Goldberg ✨)
  • dc854fd chore: update dependency shelljs to ^0.9.0 (#19524) (renovate[bot])
  • 5d57496 chore: fix some comments (#19525) (jimmycathy)
  • 9c5c6ee test: fix an assertion failure (#19500) (fisker Cheung)
  • 7a699a6 chore: remove formatting-related lint rules internally (#19473) (Josh Goldberg ✨)
  • c99db89 test: replace WebdriverIO with Cypress (#19465) (Pixel998)

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

Evolving flat config with extends
5 min read

Evolving flat config with extends

Your eslint.config.js files can now use extends to simplify your configuration.

ESLint v9.22.0 released
1 min read

ESLint v9.22.0 released

We just pushed ESLint v9.22.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.21.0 released
2 min read

ESLint v9.21.0 released

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