Repository navigation
Bug: eslint-plugin-react-hooks v.6.1.0 recommended config uses array instead of object #34679
Description
Not sure if this is technically a bug, or just a convention choice.
It's not possible to use the recommended config directly in a flat eslint config array in version 6.1.0
The recommended-latest config (now deprecated) will work, but the new recommended config will not.
The plugin is defined as:
Object.assign(plugin.configs, {
'recommended-legacy': {
plugins: ['react-hooks'],
rules: ruleConfigs,
},
'flat/recommended': [
{
plugins: {
'react-hooks': plugin,
},
rules: ruleConfigs,
},
],
'recommended-latest': [
{
plugins: {
'react-hooks': plugin,
},
rules: ruleConfigs,
},
],
recommended: {
plugins: ['react-hooks'],
rules: ruleConfigs,
},
});
The last property should be
recommended: {
plugins: {
'react-hooks': plugin,
},
rules: ruleConfigs,
},
as per https://eslint.org/docs/latest/use/configure/configuration-files#configuration-objects which states
plugins - An object containing a name-value mapping of plugin names to plugin objects. When files is specified, these plugins are only available to the matching files.
React version: 19.1.1
Steps To Reproduce
// eslint.config.js
import jsEslint from '@eslint/js';
import reactHooks from 'eslint-plugin-react-hooks';
import { defineConfig } from 'eslint/config';
export default defineConfig([
jsEslint.configs.recommended,
reactHooks.configs.recommended
]);
The current behaviour
Running eslint
Oops! Something went wrong! :(
ESLint: 9.36.0
A config object has a "plugins" key defined as an array of strings. It looks something like this:
{
"plugins": ["react-hooks"]
}
Flat config requires "plugins" to be an object, like this:
{
plugins: {
react-hooks: pluginObject
}
}
Please see the following page for information on how to convert your config object into the correct format:
https://eslint.org/docs/latest/use/configure/migration-guide#importing-plugins-and-custom-parsers
If you're using a shareable config that you cannot rewrite in flat config format, then use the compatibility utility:
https://eslint.org/docs/latest/use/configure/migration-guide#using-eslintrc-configs-in-flat-config
The expected behaviour
For it to work the same as if using reactHooks.configs['recommended-latest'] instead.
This isn't a huge deal since there are only two rules, so its easy to just skip the recommended config like the following, but it would nice to be consistent with the way other eslint plugins share their configs.
{
plugins: {
'react-hooks': reactHooksPlugin,
},
rules: {
'react-hooks/exhaustive-deps': 'error',
'react-hooks/rules-of-hooks': 'error',
},
},
Activity
cpojer commentedon Oct 2, 2025
Yup I also just ran into this, had to go back to
'react-hooks': reactHooks.josephsavona commentedon Oct 2, 2025
Thanks for reporting. I experimented with a bunch of ways to define the plugin, looking at the ESLint docs and examples and trying things out to make sure they worked. Iirc I tried defining it as you suggest and ran into issues when trying to install the plugin, but we’ll definitely take another look!
josephsavona commentedon Oct 2, 2025
Note that ESLint docs say that in v9, if you specify “recommended” in your config that it will choose “flat/recommended” if available. We define that too, as you suggest, and left “recommended” in a way that’s backwards compatible w ESLint v8. Is that upgrade to flat config not happening? Are you using the defineConfig() helper?
cpojer commentedon Oct 2, 2025
@josephsavona Could you copy what
eslint-plugin-reactdoes? It exportsreact.configs.flat.recommended. See nkzw-tech/eslint-config@c388e7f where I had to fix up the setup ofeslint-plugin-react-hookswhen upgrading to 6.1.0.Probably a different discussion, but it would be great to just take over
eslint-plugin-react, deprecate/remove some of the silly rules it has, and then merge the hooks plugin into that one. There is really no reason to have more than one ESLint plugin for React.anthonyblond commentedon Oct 2, 2025
@josephsavona Happens with defineConfig too.
I see. I didn't realise the intention was for
recommendedto be backwards compatible, and to useflat/recommended. That makes sense. I'll just do that.As an aside I'm actually using this in typescript and doing
results in a tsc error saying it doesn't have a
.configproperty. Looking at the package's declaration files its not clear why it thinks it doesn't. Not really relevant to this and easily ignored though :)brijeshb42 commentedon Oct 2, 2025
It also has typescript issue where I cannot access
reactHooksPlugin.configs.recommendedwith errorProperty 'configs' does not exist on reactHooksPluginwherereactHooksPluginis imported as -manferlo81 commentedon Oct 2, 2025
Yep!, the types are broken for
plugin.configs.The problem...
plugin.configsis defined as an empty object and then populated usingObject.assignso typescript doesn't know it's shape and therefore can't generate types correctly.https://github.com/facebook/react/blob/d74f061b6908e4841b2eb09c296ca4658dbdd38e/packages/eslint-plugin-react-hooks/src/index.ts#L28C1-L36C32
Daniel3711997 commentedon Oct 2, 2025
"eslint-plugin-react-hooks": "^6.0.0-rc.2"
Also for the new RC version, the eslint rule 'react compiler' stopped working:
Key "rules": Key "react-hooks/react-compiler": Could not find "react-compiler" in plugin "react-hooks".
RC 1 works fine
Resolve React ESLint package issues
Stanzilla commentedon Oct 2, 2025
Hah okay, I am not alone with this, I though eslint changed something yet again. cc @poteto
[eprh] Fix `recommended` config for flat config compatibility
[eprh] Fix `recommended` config for flat config compatibility
[eprh] Fix `recommended` config for flat config compatibility
9 remaining items
[eprh] Update plugin config to be compatible with flat and legacy
[eprh] Update plugin config to be compatible with flat and legacy (#3…
[eprh] Update plugin config to be compatible with flat and legacy (#3…
[eprh] Update plugin config to be compatible with flat and legacy (#3…
poteto commentedon Oct 7, 2025
Sorry everyone, this has been more frustrating than expected. eslint's docs clearly seems to be wrong, so I've tried to copy what eslint-plugin-react does in #34762.
If anyone can help me verify if this experimental release solves the issue, that would help a lot: 0.0.0-experimental-848e0e3a-20251007
kachkaev commentedon Oct 7, 2025
👋 @poteto! I tried
0.0.0-experimental-848e0e3a-20251007after6.2.0-canary-a4eb2dfa-20251006(which worked). There seems to be a regression.If I add
...eslintPluginReactHooks.configs.recommended,(as before), I get this TSC error:and this runtime error:
If I remove
..., I get this TSC error:and this runtime error:
pmmmwh commentedon Oct 7, 2025
Both type-checking and invoking ESLint works if the
flat.recommendedform is used:Daniel3711997 commentedon Oct 8, 2025
Using 6.2.0-canary-3025aa39-20251007 and configs.recommended:
⨯ ESLint: Key "rules": Key "react-hooks/react-compiler": Could not find "react-compiler" in plugin "react-hooks".
poteto commentedon Oct 8, 2025
Please use: https://www.npmjs.com/package/eslint-plugin-react-hooks/v/7.0.0-canary-4b3e662e-20251008
poteto commentedon Oct 8, 2025
@Daniel3711997 please use the
recommendedpreset in 7.0.0Daniel3711997 commentedon Oct 9, 2025
@poteto now on 7 i get this using the recommended config....⨯ ESLint: Config "UserConfig[0][7] > ExtendedConfig[11]": Key "plugins": This appears to be in eslintrc format (array of strings) rather than flat config format (object).
ArmandRedgate commentedon Oct 9, 2025
In v7, I was able to get it working like this:
Daniel3711997 commentedon Oct 10, 2025
Using this there is still not react compiler rules:
⨯ ESLint: Key "rules": Key "react-hooks/react-compiler": Could not find "react-compiler" in plugin "react-hooks".
'react-hooks/react-compiler': 'error' - It has been removed?
[eprh] Update plugin config to be compatible with flat and legacy (re…
[eprh] Update plugin config to be compatible with flat and legacy (re…