ESLint 28 🛡️ Cheatsheet
ESLint v10 is flat-config only. The .eslintrc system is gone, the config resolution starts from each file’s directory, and the Node.js floor is ^20.19.0 || ^22.13.0 || >=24 . The cheatsheet is the set of decisions that keep a v10 config loadable and a rule set predictable.
The Node.js Gate
| Version | Status |
|---|---|
^20.19.0 | Supported |
^22.13.0 | Supported |
>=24 | Supported |
v21, v23 | Dropped |
< 20.19.0 | Dropped |
Check engines.node and the CI image before touching the config. The install fails at the engine check, not at lint time.
The Flat Config Structure
| Legacy (dead) | Flat (v10) |
|---|---|
.eslintrc.* | eslint.config.js / .mjs / .ts |
extends: ["..."] | Import and spread, or defineConfig |
env: { browser: true } | languageOptions.globals |
.eslintignore | globalIgnores() or ignores |
plugins: ["react"] | plugins: { react: reactPlugin } |
The defineConfig() helper from eslint/config auto-flattens arrays and provides type safety . The globalIgnores() helper marks a block as global ignores, which is clearer than a bare ignores key .
// eslint.config.mjs — the essential v10 config
import js from "@eslint/js";
import { defineConfig, globalIgnores } from "eslint/config";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
export default defineConfig(
globalIgnores(["dist/**", "coverage/**"]),
js.configs.recommended,
tseslint.configs.recommended,
eslintConfigPrettier, // last: disables formatting rules
);
The Config Lookup Change
v9 resolved the config from the cwd. v10 resolves it from the directory of each linted file, walking upward . A monorepo with per-package configs works without flags. A project that relied on the cwd lookup can pass --config explicitly.
The v10_config_lookup_from_file flag is removed because the behavior is the default .
The eslint:recommended Update
The v10 recommended config includes new rules that were not in v9 . A project that extends js.configs.recommended sees new reports after the upgrade. Address them or disable them explicitly; the reports are the config doing what it was updated to do.
The Rule Changes
| Rule | v10 Change |
|---|---|
radix | "always" and "as-needed" deprecated; radix always required |
no-shadow-restricted-names | globalThis reported by default |
func-names | Extra array items invalid |
no-invalid-regexp | Duplicate allowConstructorFlags invalid |
no-unexpected-multiline | Checks regex literals with d and v flags |
The no-shadow-restricted-names change is the one that produces reports without any config change:
// v10 reports this by default
const globalThis = "foo";
The fix is to rename the variable or set reportGlobalThis: false .
The eslint-env Removal
The /* eslint-env */ comments are reported as errors in v10 . Replace them with languageOptions.globals:
// Before (v9)
/* eslint-env serviceworker */
// After (v10)
languageOptions: { globals: { ...globals.serviceworker } }
The Ecosystem Blocker
eslint-plugin-import 2.32.0 does not support ESLint 10 and crashes at plugin-load time with a TypeError about sourceType . The replacement is eslint-plugin-import-x, a drop-in fork with a peer range that includes ^10.0.0 .
| Package | Status |
|---|---|
eslint-plugin-import | Crashes on v10 |
eslint-plugin-import-x | v10-compatible |
The swap requires a rule-prefix change from import/ to import-x/, including in eslint-disable comments .
The typescript-eslint Setup
typescript-eslint v8 supports ESLint 10 . The type-aware mode uses projectService: true instead of the older project path .
{
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
}
The allowDefaultProject option lints config files that are not in a tsconfig.json .
The Prettier Integration
eslint-config-prettier must be last in the config array. It disables the ESLint formatting rules that conflict with Prettier, and the v10 rule updates do not change its placement requirement .
export default defineConfig(
js.configs.recommended,
tseslint.configs.recommended,
eslintConfigPrettier, // last
);
The Migration Command
The @eslint/migrate-config package converts a legacy .eslintrc into a starting flat config :
npx @eslint/migrate-config .eslintrc.json
The output is a starting point, not a finished config. Review the imports, the globals, and the plugin objects by hand.
The One-Line Summary
Flat only. Node 20.19+. Per-file config lookup. import-x over import. eslint-config-prettier last.
ESLint v10 is the cleanup release that removes the compatibility layers. The flat config is the only config, the Node.js floor is the gate, and the eslint-plugin-import swap is the ecosystem blocker. The rule updates produce new reports, and the eslint-env comments are errors. The config is an array of objects, and the defineConfig helper is the composition mechanism.
Summary
| Area | Key takeaway |
|---|---|
| Node.js | ^20.19.0 || ^22.13.0 || >=24 |
| Config | eslint.config.js only |
| Lookup | From each file’s directory |
eslint:recommended | Updated with new rules |
radix | Radix always required |
globalThis | Reported by no-shadow-restricted-names |
eslint-env | Reported as errors |
eslint-plugin-import | Swap to eslint-plugin-import-x |
| Prettier | eslint-config-prettier last |
Remember: ESLint v10 is flat-config only and Node 20.19+ only. The config lookup starts from each file’s directory, the eslint:recommended config includes new rules, and the eslint-env comments are errors. The eslint-plugin-import package is the ecosystem blocker, and eslint-plugin-import-x is the drop-in replacement. The defineConfig and globalIgnores helpers are the composition mechanism, and eslint-config-prettier stays last. The cheatsheet is the decisions, and the decisions are the migration.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!