NewsJavaScriptDeveloper Tools

ESLint v9 Dies August 6 — Migrate to v10 Before Your CI Breaks

ESLint v10 migration guide - code linting interface showing upgrade path from v9 to v10 flat config
ESLint v9 reaches end-of-life August 6, 2026

ESLint v9 reaches end-of-life on August 6 — five days from today. After that date, the v9 branch gets no security patches and no bug fixes. The migration to v10 is not complicated, but one silent gotcha in CI will catch teams that skip the checklist: the Node.js minimum version jumped, and most CI configs do not specify a precise enough version to catch it before it breaks.

What Changes in ESLint v10

ESLint v10 shipped in February 2026 and has been at v10.8.0 since July. The breaking changes fall into three categories worth understanding before you type a single command.

1. The eslintrc Format Is Gone

This one has been coming since v9. In v10, it is final: .eslintrc.json, .eslintrc.js, .eslintrc.yml — none of them work. The ESLINT_USE_FLAT_CONFIG=false environment variable no longer has any effect. Flat config (eslint.config.js) is now the only supported format, full stop.

If you already migrated to flat config during the v9 window, you are done with this part. If you have not, the codemod handles most of it automatically.

2. Node.js v18 and Early v20 Are Dropped

ESLint v10 requires ^20.19.0 || ^22.13.0 || >=24. Node 18 is completely out. Node 20.0 through 20.18 are out. Most developers running Node 22 LTS are fine, but CI pipelines are a different story. A pipeline that specifies node:20 without a patch version may pull a build image that fails silently — ESLint installs, runs, and errors on the Node version check before linting a single file.

This is the change most likely to surprise teams. The config looks right. The install succeeds. The first lint run fails with a Node version error instead of a lint error, which is confusing if you are not expecting it.

3. /* eslint-env */ Comments Are Now Lint Errors

Any file containing /* eslint-env browser */ or /* eslint-env node */ will now produce a lint error on those comments. These were deprecated in v9 and removed in v10. A codebase with years of history likely has dozens of them. Running a grep before the migration tells you exactly what you are dealing with:

grep -r "eslint-env" src/ --include="*.js" --include="*.ts"

The replacement is a globals entry in your flat config — more explicit, no magic.

How to Migrate: Four Steps

Step 1: Check Your Versions

npx eslint --version
node --version

Confirm you are on v9.x and that Node is at least 20.19.0. If Node is below that, update your local environment and CI config before touching ESLint.

Step 2: Run the Migration Codemod

If you are still on .eslintrc.json or similar, the official codemod converts it to flat config format:

npx @eslint/migrate-config .eslintrc.json

This produces an eslint.config.mjs file. Review it before committing — particularly the plugins section, where string-based plugin names become direct imports. If your .eslintrc.js contains conditional logic, the codemod only captures the evaluated output, so that logic needs manual rewriting.

Step 3: Upgrade ESLint and Dependencies

npm install --save-dev eslint@latest

If you use typescript-eslint, upgrade that as well — v8 or later is required for ESLint v10 compatibility. Then run your linter and see what surfaces.

Step 4: Remove Lingering eslint-env Comments

Use the grep from Step 1 to find remaining /* eslint-env */ comments. Replace them with a languageOptions.globals entry in eslint.config.mjs:

import globals from "globals";

export default [
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node,
      },
    },
  },
];

Run the linter again. Most projects land here in under an hour.

One More Monorepo Note

ESLint v10 now finds its config file starting from the directory of each linted file, rather than from the current working directory. For monorepos, this is an improvement — each package can have its own eslint.config.js and ESLint finds it automatically. But if you run ESLint from a root script and depend on a single root config applying everywhere, verify that config path resolution still works as expected by running a test lint across all packages.

The Upside of Getting This Done

Flat config deserves more credit than the migration friction suggests. No more silent rule inheritance from parent directories. No more YAML with escape character edge cases. No more wondering which config file wins in a cascading setup. The eslint.config.js file is a plain JavaScript module — you import, compose, and export configs the same way you do everything else in your project.

ESLint v10.8.0 is the current release, and the team is shipping minor updates monthly. The language plugin system covering CSS and Markdown is expanding. ESLint is actively investing in v10 — and that investment only shows up once you are on it.

The deadline is August 6. The migration takes an afternoon. Run the codemod, fix the Node version in CI, grep for eslint-env comments, and ship it. The official migration guide covers every edge case if you hit something unusual.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:News