Hooks’ dependency arrays are critical for correctness: omitting a variable can lead to stale values or missed updates, and disabling React’s exhaustive-deps rule without explanation makes debugging harder. eslint-plugin-strict-hooks steps in exactly when you choose to bypass react-hooks/exhaustive-deps
via an inline comment. It enforces that you document:
- Which dependencies you are intentionally leaving out.
- Why it’s safe to omit them.
Without this plugin, silent omissions can hide bugs—components using outdated variables, unexpected re-renders, or maintenance headaches when code evolves.
- Styled annotations: Recognize
// eslint-disable-line react-hooks/exhaustive-deps -- depName: reason
comments. - Detect missing mentions: Warn if a dependency used in the hook callback is not mentioned in the disable comment.
npm install --save-dev eslint-plugin-strict-hooks eslint-utils
# or
yarn add --dev eslint-plugin-strict-hooks eslint-utils
Make sure you also have React Hooks rules available (from eslint-plugin-react-hooks
) in your project:
npm install --save-dev eslint-plugin-react-hooks
# or
yarn add --dev eslint-plugin-react-hooks
Add strict-hooks
alongside react-hooks
in your ESLint config. Our plugin adds an extra layer on top of the standard exhaustive-deps
checks—it does not replace or disable them.
{
"plugins": ["react-hooks", "strict-hooks"],
"rules": {
// Keep the built-in exhaustive-deps rule enabled
"react-hooks/exhaustive-deps": "warn",
// Add this rule to enforce documented disables
"strict-hooks/explicit-exhaustive-deps-disable": "warn"
}
}
Require a comment explanation when disabling exhaustive-deps.
useEffect(() => {
fetchData();
}, []); // eslint-disable-line react-hooks/exhaustive-deps -- fetchData: memoized
useEffect(() => {
fetchData();
}, []); // eslint-disable-line react-hooks/exhaustive-deps
Error: You've disabled exhaustive-deps, but you need to document why 'fetchData' is safe to omit.
Currently, eslint-plugin-strict-hooks
has no configuration options—just enable the rule directly.
{
"plugins": ["strict-hooks"],
"rules": {
"strict-hooks/explicit-exhaustive-deps-disable": "warn"
}
}
- Fork the repo
- Install dependencies:
yarn install
- Run tests in sandbox:
npm run test:sandbox
- Submit a PR against
main
Future Additions
- Support for
eslint-disable-next-line react-hooks/exhaustive-deps
comments across multiple lines. - Autofix suggestions to automatically append missing dependencies with placeholders.
- Configurable support for custom hook names (e.g.
useDebouncedEffect
). - Optional JSON output of dependency diffs for CI integrations.
- TypeScript-specific enhancements, such as respecting type-only imports and interface properties.
Current Limitations
- Only recognizes inline
// eslint-disable-line
comments, notdisable-next-line
or block disables. - No built-in autofix; suggestions must be applied manually.
- Assumes JavaScript/JSX source; some edge cases in TypeScript projects may not be fully covered.
- Does not track destructured nested properties beyond direct member expressions.
- Relies on ESLint scope analysis; unusual AST transforms or preprocessors may produce false positives/negatives.
MIT - see LICENSE