Open-Source Wikis

/

React

/

Packages

/

eslint-plugin-react-hooks

facebook/react

eslint-plugin-react-hooks

Active contributors: poteto, mvitousek, mofeiZ, josephsavona

Purpose

packages/eslint-plugin-react-hooks/ is the official ESLint plugin enforcing the Rules of Hooks. Historically it shipped two rules:

  • react-hooks/rules-of-hooks — hooks must be called at the top level, only from React functions, in the same order every render.
  • react-hooks/exhaustive-depsuseEffect/useMemo/useCallback/useImperativeHandle/useLayoutEffect dependency arrays must include every reactive value used.

Starting with v7 (in this repo's tree), the plugin has absorbed a much larger body of compiler-aware lint rules — checks that only make sense if you have the React Compiler in mind, even if you aren't running it. The plugin is dogfooded against itself in this repo's own ESLint config.

Directory layout

packages/eslint-plugin-react-hooks/
├── index.js                           # entry — exports rules + recommended config
├── package.json
├── tsconfig.json                      # TypeScript-typed despite living in the runtime tree
├── README.md / CHANGELOG.md
├── src/
│   ├── rules/                         # the rule implementations
│   │   ├── RulesOfHooks.ts            # rules-of-hooks
│   │   ├── ExhaustiveDeps.ts          # exhaustive-deps
│   │   ├── ComponentHookFactories.ts  # disallow component/hook factories with no params
│   │   └── ... (compiler-aware rules)
│   ├── compiler/                      # compiler-driven analysis used by some rules
│   └── utils/
└── __tests__/                         # ~150 fixture-driven tests

Key rules

Rule File Description
react-hooks/rules-of-hooks packages/eslint-plugin-react-hooks/src/rules/RulesOfHooks.ts The original rule. Walks the AST, builds a CFG of where hooks are called, fails if a hook is called inside a conditional/loop/return path.
react-hooks/exhaustive-deps packages/eslint-plugin-react-hooks/src/rules/ExhaustiveDeps.ts Statically infers the closure of an effect callback and compares it with the declared deps array. Suggests autofix.
react-hooks/component-hook-factories (deprecated/removed in v7.1.1, see #36307) (was) ComponentHookFactories.ts Was meant to forbid generating components/hooks at runtime. Replaced by compiler-driven equivalents.
Newer compiler-aware rules src/rules/*.ts These piggy-back on the React Compiler's analysis to catch patterns like "set-state-in-effect" or "missing key" with much better recall.

The rule list and recommended config are exported from packages/eslint-plugin-react-hooks/index.js and src/index.ts.

How it works

exhaustive-deps is the more interesting of the two. It:

  1. Finds calls to one of the dep-array hooks (useEffect, useMemo, ...).
  2. Statically analyzes the callback's referenced bindings and classifies each as "stable" (refs, dispatchers from useState/useReducer, function declarations) or "reactive" (props, state, anything else from the component scope).
  3. Compares with the declared dep array and reports the diff.
  4. Provides an autofix that adds/removes deps.

The classification logic is in packages/eslint-plugin-react-hooks/src/rules/ExhaustiveDeps.ts. Most bug reports against this plugin land here.

rules-of-hooks is simpler — it builds a CFG, walks each path, and checks that hook calls have no conditional ancestors. It also enforces "only call from React function components or custom hooks" (where "custom hook" means "a function whose name starts with use").

Compiler-aware additions

Starting with v7, the plugin can do deeper analysis when the React Compiler is available. The compiler's analyses are exposed through packages/eslint-plugin-react-hooks/src/compiler/ and used to power rules like:

  • Detection of setState inside a render that wasn't already on the path of a transition.
  • More accurate "exhaustive-deps" for hooks the user has declared as effect events.
  • Detection of mutations of frozen values.

The compiler-aware rules can be enabled selectively via the plugin's config — they are listed in index.js but not in the recommended preset by default.

Build / test / publish

The plugin is TypeScript and uses tsup for building. Tests use Jest with rule-tester fixtures. The published package is named eslint-plugin-react-hooks. Releases are tagged in this repo as e.g. eslint-plugin-react-hooks@7.1.1. The publish flow is the same as the runtime — driven by scripts/release/.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

eslint-plugin-react-hooks – React wiki | Factory