ESLint React: composable lint plugins split by the part of React you use
Composable ESLint rules for React and friends.
At a glance
- What is it?
- eslint-react publishes six modular ESLint plugins plus a unified bundle, with presets that turn rule groups on and off and type-aware variants that need the TypeScript project service. It suits a React codebase on TypeScript that wants rules for JSX, Server Components, DOM and Web APIs without adopting every opinion at once.
- Who is it for?
- eslint-react fits a React and TypeScript codebase that has outgrown the classic eslint-plugin-react rules, particularly one using React Server Components or the DOM and Web API surfaces, since the plugin set is split by exactly those areas and each can be enabled alone.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Six plugins split by the part of React they cover
The core idea of this project is that React linting is not one problem. Six modular packages are published, and each covers a different surface. eslint-plugin-react-x holds the X rules, described as renderer-agnostic and compatible with an x-platform target. eslint-plugin-react-jsx holds React flavoured JSX rules. eslint-plugin-react-rsc holds the rules for React Server Components. eslint-plugin-react-dom holds the DOM specific rules for React DOM, and eslint-plugin-react-web-api the rules for interacting with Web APIs. The sixth is eslint-plugin-react-naming-convention, for naming rules. The split matters in practice because a Server Components codebase and a browser codebase have different rule sets, and a single plugin that carries both forces you to disable half of it. A unified package, @eslint-react/eslint-plugin, is also published for people who would rather take everything at once.
Installing needs ESLint 10 and Node 20.19, which is the first thing to check
The installation section starts with minimum versions, and they are not modest. Node.js 20.19.0, ESLint 10.0.0 and TypeScript 5.0.0 are all required. If your project is on ESLint 9, this is a blocker rather than a warning, and the migration guides linked from the readme cover moving from eslint-plugin-react and from eslint-plugin-react-hooks rather than from an older ESLint, so the ESLint upgrade is on you. The install itself is one command that pulls in the TypeScript ESLint package and the unified plugin.
npm install --save-dev typescript-eslint @eslint-react/eslint-pluginThe setup that follows writes a flat config file. The example in the readme is the whole file, and it shows the three recommended rule sets being extended in one place, the ESLint JS recommended rules, the TypeScript ESLint recommended rules and the ESLint React recommended-typescript rules, with a files pattern covering TypeScript and TSX. It also shows the parser options with the project service enabled and the tsconfigRootDir set to the directory of the config file itself, which is what makes the type-aware rules work.
The project service is what pays for the type-aware rules
Look closely at the parser options in the documented config, because that block is the difference between the type-aware presets working and not working. The parser is the TypeScript ESLint parser, and the parser options enable projectService with the tsconfigRootDir pointing at import.meta.dirname. The project service is described in the comment as being for better TypeScript integration, and the practical effect is that ESLint can resolve type information for the files it lints rather than only looking at syntax. That is what the type-checked presets need, and the cost is real: the linter has to load your TypeScript program, which is why a monorepo with several packages can see noticeably slower lint runs. The readme also claims performance as a feature, citing large codebases, editor responsiveness and CI pipelines, and the type-aware rules are the part of that claim you should measure on your own repository before you commit to a preset.
Presets compose from six named groups, and the disable list is longer than the enable list
The preset system is where the composability claim lives. The six bare bones presets each enable one area: x for React, jsx for React flavoured JSX, rsc for React Server Components, dom for React DOM, web-api for Web APIs and naming-convention for naming. Everything else is built on top of those. The recommended preset enables all six for general purpose React and React DOM work, and strict is the same with additional strict rules. The TypeScript family is a different axis rather than a stricter one: recommended-typescript disables the rules TypeScript itself can enforce, recommended-type-checked adds the rules that need type information, and strict-typescript and strict-type-checked combine the strict rules with those two ideas. The disable presets are the other half, with one to switch off each of jsx, rsc, dom, web-api and naming-convention, one for rules carrying an experimental flag, one for the type-checked rules, and two that turn off rules from eslint-plugin-react and eslint-plugin-react-hooks that conflict with the ones here.
Rules are namespaced per plugin, and severity is yours to set
The rule identifiers follow the package they live in, and the documented override shows the shape. The example config sets a single rule to warn.
rules: {
"@eslint-react/no-missing-key": "warn",
},The namespacing is a direct consequence of the split, since a rule that lives in the naming convention plugin has a different prefix from one in the DOM plugin, and knowing the prefix tells you which package has to be installed for that rule to resolve. The feature list also names fully customizable rule severity levels as a first class property, with the ability to enforce or relax rules as needed, and the no-missing-key example is the smallest possible demonstration of that. Context-aware linting is the other claim, described as rules that understand the context of your code and your project configuration to give more accurate results, which is the part that depends on the type-aware setup rather than the preset names.
A monorepo with Nx, examples for Preact and oxlint, and a weekly release cadence
The repository is a pnpm and Nx monorepo for the six plugins, with a packages directory, a plugins directory, a .pkgs directory, apps for the documentation site, an examples directory, a testing directory and a scripts directory. The examples are more revealing than they look, because they include a preact example, a preact-compat example, a react-dom example, a react-dom-with-custom-rules example, a react-dom-oxlint example, a next example and a tanstack-start example. The oxlint and preact ones matter, because they show the rules being used outside the plain React and ESLint combination. The build is driven by tsdown according to the build badge, the scripts run Nx run-many across the package and plugin directories, and the formatting is handled by dprint. The release cadence is very fast, with v5.28.3, v5.28.2 and v5.28.1 published on three consecutive days in October 2026, and the last push to the repository was on 2026-10-20. The project is MIT licensed with a LICENSE file, a SECURITY.md and a CHANGELOG.
Editorial conclusion
eslint-react fits a React and TypeScript codebase that has outgrown the classic eslint-plugin-react rules, particularly one using React Server Components or the DOM and Web API surfaces, since the plugin set is split by exactly those areas and each can be enabled alone. It does not fit a project still on ESLint 9 or Node 18, because the stated minimums are ESLint 10.0.0, Node 20.19.0 and TypeScript 5.0.0, and it does not fit a team that wants a single opinionated switch rather than a set of choices. Before you install it, run the install and setup steps as given, pick the preset that matches whether you want type-aware rules, and read the conflict rules in the presets list, since they exist to switch off overlapping rules from the two plugins it is meant to replace.
Frequently asked questions
What is ESLint React and what does it give you?
It is a set of composable ESLint rules for React and friends, published as six modular plugins covering X rules, React flavoured JSX, React Server Components, React DOM, Web APIs and naming conventions, plus a unified plugin that combines them. The rules are severity-configurable and can use type information from your TypeScript project.
Which versions of Node, ESLint and TypeScript does eslint-react need?
The stated minimums are Node.js 20.19.0, ESLint 10.0.0 and TypeScript 5.0.0. The install command is npm install --save-dev typescript-eslint @eslint-react/eslint-plugin, and the setup writes a flat config file extending the recommended rule sets.
Which preset should I use for a TypeScript React project?
The TypeScript specialised presets are recommended-typescript, which is the recommended set with rules TypeScript can enforce disabled, recommended-type-checked, which adds the rules that require type information, and strict-typescript and strict-type-checked, which combine the strict rules with those ideas.
How do I migrate from eslint-plugin-react to eslint-react?
The readme links to dedicated migration guides for moving from eslint-plugin-react and from eslint-plugin-react-hooks. The presets also include disable-conflict-eslint-plugin-react and disable-conflict-eslint-plugin-react-hooks, which switch off rules in the older plugins that conflict with the ones in this project.
Do the type-aware rules need extra setup?
Yes. The documented configuration enables the TypeScript ESLint parser with projectService set to true and tsconfigRootDir pointing at the config file directory, which is what lets the linter resolve type information for the files it checks.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rel1cx-eslint-react)Was this useful?