@jmlweb/eslint-config-react
v6.0.4
Published
ESLint configuration for React libraries with TypeScript, extending base config with React-specific rules
Maintainers
Readme
@jmlweb/eslint-config-react
ESLint flat config for React with TypeScript. Extends
@jmlweb/eslint-config-basewith React, Hooks and JSX rules.
🔧 Maintenance mode: only dependency and security updates, no new rules. For new projects use
@jmlweb/oxlint-config-react. To move an existing project, see the migration guide.
✨ Features
- ⚛️ React rules:
@eslint-reactrecommended-typescriptpreset - 🪝 Hooks and React Compiler rules: official
eslint-plugin-react-hooksrecommendedpreset, applied to every file - 🧩 JSX style: PascalCase, self-closing, no needless braces or fragments, sorted props
- 🔒 Strict TypeScript: everything from
@jmlweb/eslint-config-base - 🎨 Prettier compatible: disables rules that conflict with Prettier
📦 Installation
npm install --save-dev @jmlweb/eslint-config-react @jmlweb/eslint-config-base eslint @eslint/js typescript-eslint eslint-config-prettier eslint-plugin-simple-import-sort @eslint-react/eslint-plugin @stylistic/eslint-plugin eslint-plugin-perfectionist eslint-plugin-react-hooks💡 Upgrading? See the Migration Guide.
🚀 Quick Start
// eslint.config.js
import reactConfig from '@jmlweb/eslint-config-react';
export default [
...reactConfig,
// Project-specific overrides
];💡 Examples
Test overrides and ignores
// eslint.config.js
import reactConfig from '@jmlweb/eslint-config-react';
export default [
...reactConfig,
{
files: ['**/*.test.tsx', '**/*.spec.tsx'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@eslint-react/no-array-index-key': 'off',
},
},
{
ignores: ['dist/', 'build/', 'node_modules/'],
},
];Explicit React version
// eslint.config.js
import reactConfig from '@jmlweb/eslint-config-react';
export default [
...reactConfig,
{
settings: {
'react-x': {
version: '19.2', // default: 'detect'
},
},
},
];Lower a strict Hooks rule while adopting
// eslint.config.js
import reactConfig from '@jmlweb/eslint-config-react';
export default [
...reactConfig,
{
rules: {
'react-hooks/set-state-in-effect': 'warn',
},
},
];📋 Configuration Details
Scope
| Rules | Applied to |
| ---------------------------------------------------- | -------------------------- |
| @eslint-react preset, react-hooks preset | all files (hooks in .ts) |
| JSX style, import sorting, PascalCase function names | **/*.tsx, **/*.jsx |
Hooks rules come from eslint-plugin-react-hooks. @eslint-react's ports of the same rules are turned off, so each problem is reported once as react-hooks/*.
Key rules
| Rule | Level | Description |
| ------------------------------------------------- | ------- | -------------------------------------------- |
| react-hooks/rules-of-hooks | error | Rules of Hooks |
| react-hooks/exhaustive-deps | warn | Hook dependencies |
| react-hooks/purity, refs, immutability, ... | error | React Compiler rules |
| @eslint-react/no-missing-key | error | Missing keys in lists |
| @eslint-react/no-array-index-key | warn | Array index as key |
| @eslint-react/jsx-no-children-prop | error | children passed as a prop |
| @eslint-react/jsx-no-useless-fragment | error | Unnecessary fragments |
| @eslint-react/dom-no-unknown-property | error | Unknown DOM properties (class, ...) |
| @eslint-react/dom-no-unsafe-target-blank | error | target="_blank" without rel |
| @stylistic/jsx-pascal-case | error | PascalCase component names |
| @stylistic/jsx-self-closing-comp | error | Self-close elements without children |
| @stylistic/jsx-curly-brace-presence | error | No unnecessary curly braces |
| perfectionist/sort-jsx-props | error | Reserved, shorthand, regular, then callbacks |
The naming convention is relaxed so functions may be PascalCase (components). The React version is auto-detected.
🔄 Import Sorting
Imports are sorted and type-only imports are enforced.
Before:
import { Component } from './component';
import React, { useState } from 'react';
import { User } from './types';After eslint --fix:
import React, { useState } from 'react';
import { type User } from './types';
import { Component } from './component';🎯 When to Use
- ✅ React libraries and apps written in TypeScript
- ✅ Strict Hooks and React Compiler checks, even without the Compiler
- ✅ Consistent JSX style across a team
For non-React TypeScript use @jmlweb/eslint-config-base. For new projects prefer @jmlweb/oxlint-config-react.
🔧 Extending the Configuration
Spread the config, then add objects after it. Later entries win.
// eslint.config.js
import reactConfig from '@jmlweb/eslint-config-react';
export default [
...reactConfig,
{
files: ['**/*.tsx'],
rules: {
'@stylistic/jsx-curly-brace-presence': 'off',
},
},
];📝 Usage with Scripts
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix"
}
}npm run lint📋 Requirements
- Node.js >= 22.12.0
- ESLint ^9.0.0 || ^10.0.0 (flat config)
- React >= 17 (modern JSX transform)
- TypeScript project with a
tsconfig.json(versions supported by typescript-eslint 8)
📦 Peer Dependencies
eslint(^9.0.0 || ^10.0.0)@eslint/js(^9.0.0 || ^10.0.0)typescript-eslint(^8.0.0)eslint-config-prettier(^9.1.0 || ^10.0.0)eslint-plugin-simple-import-sort(^12.0.0 || ^13.0.0 || ^14.0.0)@eslint-react/eslint-plugin(^5.0.0)@stylistic/eslint-plugin(^5.0.0)eslint-plugin-perfectionist(^5.0.0)eslint-plugin-react-hooks(^7.0.0)@jmlweb/eslint-config-base(^3.0.3)
🔗 Related Packages
@jmlweb/eslint-config-base: TypeScript config (extended by this package)@jmlweb/oxlint-config-react: Oxlint equivalent, recommended for new projects@jmlweb/tsconfig-react: TypeScript config for React@jmlweb/prettier-config-base: Prettier config (maintenance mode)
🔄 Migration Guide
5.x to 6.0
Hooks rules now come from eslint-plugin-react-hooks' recommended preset instead of two hand-picked rules.
- React Compiler rules are enabled, most as errors (
purity,refs,immutability,set-state-in-effect,static-components, ...) - Hooks rules also apply to
.tsfiles
- Run
npx eslint .and fix the new reports. - To adopt gradually, lower rules to
warn, for example'react-hooks/set-state-in-effect': 'warn'.
4.x to 5.0
eslint-plugin-react is replaced by @eslint-react/eslint-plugin, which supports ESLint 10.
- Remove
eslint-plugin-react; add@eslint-react/eslint-plugin,@stylistic/eslint-pluginandeslint-plugin-perfectionist react/*rules are now@eslint-react/*,@stylistic/*orperfectionist/sort-jsx-propsjsx-boolean-value,jsx-fragmentsandno-unescaped-entitiesare no longer enforcedsettings.react.versionis nowsettings['react-x'].version
Swap the dependencies:
npm uninstall eslint-plugin-react npm install --save-dev @eslint-react/eslint-plugin @stylistic/eslint-plugin eslint-plugin-perfectionistRename
react/*rules in overrides andeslint-disablecomments (react/no-array-index-keybecomes@eslint-react/no-array-index-key).Run
npx eslint --fix .and review the remaining reports.
3.x to 4.0
Node.js >= 22.12.0 is now required (see the Changelog).
📄 License
MIT
