# ESLint: an AST-based pattern checker for JavaScript, and what version 10 expects from you

> ESLint parses JavaScript with Espree and evaluates rules against the resulting AST. Version 10 requires a modern Node.js runtime and a flat config file, and its release cadence means upgrading is a recurring task rather than a one-off.

**eslint/eslint** — Find and fix problems in your JavaScript code.

- Repository: https://github.com/eslint/eslint
- Website: https://eslint.org
- Stars: 27,521 · Forks: 5,192
- Language: JavaScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/eslint-eslint

## What ESLint actually checks, and who ends up running it

ESLint reports on patterns found in ECMAScript and JavaScript code. The README compares it to JSLint and JSHint and then names the differences: it parses with Espree, it evaluates patterns against an AST rather than against text, and every rule is a plugin that can be added at runtime. That third point is the one that changes how teams use it. A rule is not a compiler feature you wait for. It is a module you can write, publish, and load into the same run as the built-in ones.

The audience is anyone who reviews JavaScript. If a codebase has one author and no CI, a linter mostly produces warnings that author ignores. If several people touch the same files, the value is that a rule like prefer-const or no-constant-binary-expression produces the same verdict on every machine, and the verdict can be wired into an exit code. ESLint's error levels are built for exactly that split: "off" or 0 disables a rule, "warn" or 1 reports without affecting the exit code, and "error" or 2 sets the exit code to 1. A team can adopt a rule as a warning, watch the noise, then promote it.

ESLint is not a formatter, and the README is explicit that Prettier does a different job. It also does not understand React semantics just because it parses JSX. JSX parsing has to be enabled in configuration, and the README recommends eslint-plugin-react if you want React-specific rules.

## Espree, the AST, and why rules are plugins

The pipeline described in the README is short. Espree turns source text into an AST. Rules then inspect that tree and report. Because the intermediate representation is a tree rather than a token stream, a rule can reason about structure: whether a binding is reassigned, whether an expression is constant, whether a branch is reachable in the syntactic sense. This is also why the tool is described as a pattern checker rather than a type checker. It sees one file's syntax, not the types flowing between modules.

The plugin model is the architecture, not an add-on. The README states that every single rule is a plugin and that more can be added at runtime. Practically, that means the boundary between core and third-party rules is a packaging decision, not a capability boundary. It also explains the ecosystem shape: parser plugins such as @babel/eslint-parser exist for syntax Espree does not accept, and rule plugins exist for frameworks whose semantics the core does not model.

The parser has a stated policy on new syntax. It officially supports the latest final ECMAScript standard. For stage 3 proposals, the team will change core rules to avoid crashing when the proposal is implemented with correct experimental ESTree syntax, but it will not necessarily make rules warn on more or fewer cases. For that, the README points to other parsers and rule plugins. That is a deliberate boundary, and it means a project using bleeding-edge syntax should expect to bring its own parser.

## Installing ESLint and running it on a real file

The README gives one setup command. Running it scaffolds a config for the project rather than dropping a bare dependency in place.

```bash
npm init @eslint/config@latest
```

After that, the README shows how to lint a file or directory. The npx prefix means you do not need a global install; the binary declared in package.json is ./bin/eslint.js, exposed as eslint.

```bash
npx eslint yourfile.js
```

Configuration lives in eslint.config.js. The README's example imports defineConfig from eslint/config and exports an array of config objects. Each object can scope itself with a files glob and then set rules. Here the two rules are set at different error levels, which is the normal way to start: one warning you intend to fix, one error you intend to enforce.

```js
import { defineConfig } from "eslint/config";

export default defineConfig([
	{
		files: ["**/*.js", "**/*.cjs", "**/*.mjs"],
		rules: {
			"prefer-const": "warn",
			"no-constant-binary-expression": "error",
		},
	},
]);
```

If you use pnpm, the README recommends an .npmrc with auto-install-peers=true and node-linker=hoisted, on the grounds that this installs dependencies in a way closer to npm and is less likely to produce errors. That is a compatibility note, not a preference.

```text
auto-install-peers=true
node-linker=hoisted
```

## The Node.js and TypeScript floors in version 10

The prerequisites section is the least forgiving part of the README. ESLint requires Node.js ^20.19.0, ^22.13.0, or >=24, built with SSL and ICU support. Official Node.js distributions always include both, so the practical constraint is the version range. If your CI image or a developer machine sits on an older release line, ESLint will not run there, and that is a migration task before it is a linting task.

TypeScript type definitions have their own floor: TypeScript 5.3 or later if you consume ESLint's types. Note that this is about the types ESLint ships, not about linting TypeScript source, which the README handles through the parser-and-plugin route rather than through the core parser.

The version support policy is worth reading before you pin anything. The team provides ongoing support for the current version and six months of limited support for the previous version, where limited means critical bug fixes, security issues, and compatibility issues only. Commercial support for current and previous versions is offered through partners named in the README, Tidelift and HeroDevs. For a team that cannot upgrade on the project's schedule, that partner route is the stated option rather than an extended community branch.

## Where ESLint stops: syntax extensions and unshipped semantics

The clearest limitation is that parsing JSX is not the same as understanding React. The README says this directly and points to eslint-plugin-react for React semantics. A team that enables JSX parsing and assumes hooks rules come along will find they do not.

The second limitation is the experimental-syntax policy. Core rules are adjusted so they do not crash on stage 3 proposals written with correct experimental ESTree syntax, but the README does not promise that rules will flag the right cases for that syntax. If your codebase leans on proposals, or on language extensions beyond JSX such as Flow or TypeScript, the README treats those as case-by-case and steers you to other parsers and rule plugins. Babel users are pointed at @babel/eslint-parser and @babel/eslint-plugin.

The third is scope. ESLint reads files. It does not resolve your module graph the way a type checker does, and it does not format. A team looking for one tool that enforces style and catches type errors will end up assembling several, which is exactly the arrangement the README describes for Prettier.

Finally, there is no rollback story in the README. If a rule upgrade starts flagging thousands of lines, the documented lever is the error level: drop the rule to "warn", or to "off", and the exit code stops failing. That is a per-rule switch, not a version rollback.

## ESLint against Prettier, and against parser-based alternatives

The alternative the README itself addresses is Prettier, and the difference is categorical rather than incremental. ESLint is a linter looking for problematic patterns. Prettier is a code formatter. They answer different questions, and the README says using both is common, pointing to Prettier's documentation for how to make them cooperate. If your only complaint is inconsistent whitespace, adding ESLint will not fix it, and a formatting rule set inside ESLint is a workaround rather than the intended division of labor.

The other alternative is a different parser feeding the same ESLint rule engine. @babel/eslint-parser and @babel/eslint-plugin exist so Babel users can reach options Babel supports. That is not a competing linter; it is a swap of the front end while keeping the rule model. The trade-off is that you now maintain parser configuration in addition to rule configuration, and rule behavior can depend on which parser produced the tree.

The README also positions ESLint historically against JSLint and JSHint, naming Espree-based parsing, AST evaluation, and full pluggability as the differences. A project already on JSHint that only needs basic pattern checks has a working setup; the reason to move is the plugin model and the rule ecosystem, not raw detection ability.

## Maintenance, upgrades and the MIT licence

The repository is not archived, and the last push was on 2026-09-18, with v10.11.0 released the same day and v10.10.0 on 2026-09-04. Releases arrive on a short cycle, so an ESLint dependency is something you update rather than install once. The version support policy gives the shape of that work: the current version gets ongoing support, the previous version gets six months of limited support covering critical bugs, security issues, and compatibility issues. Anything older is outside the stated window.

The upgrade cost concentrates in configuration. Version 10 uses eslint.config.js with defineConfig, and older tutorials circulating online show a different format. Plugin compatibility is the other variable, since every rule is a plugin and third-party plugins must expose an entry point the current config system can load. The README's pnpm note about auto-install-peers and node-linker=hoisted is a small example of how package-manager behavior interacts with plugin resolution.

Licensing is MIT, which is permissive and imposes few conditions on use in proprietary codebases. This is a description of the licence field, not legal advice; if your organization has specific obligations around attribution or dependency review, that is a question for your own counsel.

## Conclusion

Adopt ESLint if you maintain JavaScript or TypeScript that more than one person edits, and you want rule violations to fail a command rather than a review comment. Skip it if you only need formatting: Prettier is the formatter, and the README treats them as separate jobs. Before rolling it out, verify your Node.js version satisfies ^20.19.0, ^22.13.0 or >=24, and check whether any plugin you depend on has a flat-config entry point, because the config format in version 10 is not the eslintrc format older tutorials show.

## FAQ

### What is ESLint used for?

ESLint identifies and reports on patterns found in ECMAScript and JavaScript code. It parses with Espree, evaluates rules against an AST, and every rule is a plugin that can be added at runtime.

### How do I run ESLint?

The README shows npx eslint yourfile.js after scaffolding a config. Running it on a file or directory reports rule violations, and a rule set to "error" or 2 makes the exit code 1.

### Is ESLint obsolete?

The repository is not archived, and the last push was on 2026-09-18, the same day v10.11.0 was released. The README also describes a version support policy covering the current version and six months of limited support for the previous one.

### What is ESLint vs Prettier?

The README states they have different jobs: ESLint is a linter looking for problematic patterns, and Prettier is a code formatter. It says using both is common and points to Prettier's documentation for configuring them together.

### How do I install ESLint?

The README gives npm init @eslint/config@latest as the install-and-configure command. Prerequisites are Node.js ^20.19.0, ^22.13.0, or >=24, and TypeScript 5.3 or later if you use ESLint's type definitions.

### How do I use ESLint with TypeScript?

The README does not document a TypeScript parser setup. It states that ESLint's parser officially supports the latest final ECMAScript standard, and that language extensions beyond that are handled case by case, with other parsers and rule plugins recommended.

## Sources

- [eslint/eslint on GitHub](https://github.com/eslint/eslint)
- [License: MIT](https://github.com/eslint/eslint/blob/main/LICENSE)
- [Project website](https://eslint.org)
- [README](https://github.com/eslint/eslint/blob/main/README.md)
- [Releases](https://github.com/eslint/eslint/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/eslint-eslint
