When I tried the config snippet in the question by @Jonathan Kasser, I got an error: TypeError: context.getSource is not a function.

The solution is to use fixupPluginRules from @eslint/compat (you need to install this), so my eslint.config.js has a separate object in the config array:

import { fixupPluginRules } from "@eslint/compat";

  // Even though eslint-plugin-react-hooks exposes configs.recommended, it is not yet compatible with the flat file config, 
  // because it has plugins: [ 'react-hooks' ] property, but plugins should be an object
  // Once it is supported, replace with: eslintPluginReactHooks.configs.recommended,
  {
    plugins: {
      "react": reactPlugin, // remove this if you already have another config object that adds the react plugin
      "react-hooks": fixupPluginRules(eslintPluginReactHooks),
    },
    rules: {
      ...eslintPluginReactHooks.configs.recommended.rules,
    },
  },

Resources

  • https://github.com/t3-oss/create-t3-turbo/issues/984#issuecomment-2210934687

Proof it works

I've confirmed this by having a code that should error, and saw the error:

  const [first, setfirst] = useState("");
  useEffect(() => {
    console.log(first);
  }, []);
8:6  warning  React Hook useEffect has a missing dependency: 'first'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
Answer from Ben Butterworth on Stack Overflow
🌐
GitHub
github.com › jsx-eslint › eslint-plugin-react
GitHub - jsx-eslint/eslint-plugin-react: React-specific linting rules for ESLint · GitHub
This plugin exports a recommended configuration that enforces React good practices. To enable this configuration use the extends property in your .eslintrc config file:
Starred by 9.3K users
Forked by 2.7K users
Languages   JavaScript
🌐
ESLint
eslint.org › blog › 2025 › 03 › flat-config-extends-define-config-global-ignores
Evolving flat config with extends - ESLint - Pluggable JavaScript Linter
import { defineConfig } from "eslint/config"; import js from "@eslint/js"; import tailwind from "eslint-plugin-tailwindcss"; import reactPlugin from "eslint-plugin-react"; import eslintPluginImportX from "eslint-plugin-import-x"; import exampleConfigs from "eslint-config-example"; export default defineConfig( { files: ["**/*.js"], plugins: { js, tailwind }, extends: [ "js/recommended", // load from js.configs.recommended "tailwind/flat/recommended", // load from tailwind.configs['flat/recommended'] reactPlugin.configs.flat.recommended, eslintPluginImportX.flatConfigs.recommended, ] }, // apply an array config to a subset of files { files: ["**/src/safe/*.js"], extends: [exampleConfigs] }, // your modifications { rules: { "no-unused-vars": "warn" } } );
🌐
GitHub
github.com › facebook › react › issues › 28313
eslint-plugin-react-hooks & "Flat Config" (ESLint 9) · Issue #28313 · facebook/react
February 13, 2024 - // eslint.config.js import eslint from "@eslint/js"; import hooksPlugin from "eslint-plugin-react-hooks"; export default [ eslint.configs.recommended, { plugins: { "react-hooks": hooksPlugin, }, rules: hooksPlugin.configs.recommended.rules, }, ]; Most community plugins provide a more convenient wrapper. For example, eslint-plugin-jsdoc provides a jsdoc.configs['flat/recommended'] object:
Author   JoshuaKGoldberg
🌐
GitHub
github.com › vercel › next.js › discussions › 49337
How to use new "flat config" approach in Eslint? · vercel/next.js · Discussion #49337
Sooo in case people try to set up the flat config with the new typescript-eslint instead of next/typescript at this moment looks like this setup work: import eslint from "@eslint/js"; import tseslint from "typescript-eslint"; import { flatConfig } from "@next/eslint-plugin-next"; import eslintPluginReactHooks from "eslint-plugin-react-hooks"; import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; export default tseslint.config( flatConfig.recommended, flatConfig.coreWebVitals, { files: ["**/*.ts", "**/*.tsx"], extends: [ eslint.configs.recommended, tseslint.configs.recommended, // or more strict config (e.g.
Author   vercel
🌐
DEV Community
dev.to › aolyang › eslint-9-flat-config-tutorial-2bm5
ESLint 9 Flat config tutorial - DEV Community
August 5, 2024 - Finally, you can get a really simple flat config (github Gist): import globals from "globals" import { fixupConfigRules } from "@eslint/compat" import pluginReactConfig from "eslint-plugin-react/configs/recommended.js" import jsLint from "@eslint/js" import tsLint from "typescript-eslint" import vueLint from "eslint-plugin-vue" import stylistic from "@stylistic/eslint-plugin" export default [ // config parsers { files: ["**/*.{js,mjs,cjs,ts,mts,jsx,tsx}"], }, { files: ["*.vue", "**/*.vue"], languageOptions: { parserOptions: { parser: "@typescript-eslint/parser", sourceType: "module" } } }, //
Top answer
1 of 4
10

When I tried the config snippet in the question by @Jonathan Kasser, I got an error: TypeError: context.getSource is not a function.

The solution is to use fixupPluginRules from @eslint/compat (you need to install this), so my eslint.config.js has a separate object in the config array:

import { fixupPluginRules } from "@eslint/compat";

  // Even though eslint-plugin-react-hooks exposes configs.recommended, it is not yet compatible with the flat file config, 
  // because it has plugins: [ 'react-hooks' ] property, but plugins should be an object
  // Once it is supported, replace with: eslintPluginReactHooks.configs.recommended,
  {
    plugins: {
      "react": reactPlugin, // remove this if you already have another config object that adds the react plugin
      "react-hooks": fixupPluginRules(eslintPluginReactHooks),
    },
    rules: {
      ...eslintPluginReactHooks.configs.recommended.rules,
    },
  },

Resources

  • https://github.com/t3-oss/create-t3-turbo/issues/984#issuecomment-2210934687

Proof it works

I've confirmed this by having a code that should error, and saw the error:

  const [first, setfirst] = useState("");
  useEffect(() => {
    console.log(first);
  }, []);
8:6  warning  React Hook useEffect has a missing dependency: 'first'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
2 of 4
4

[email protected] was released a few weeks ago with "stable" eslint v9 support. If you can upgrade, then see https://github.com/facebook/react/issues/28313#issuecomment-2408157792 for a sample configuration for now.

Also, follow this thread if interested in documentation refresh

🌐
npm
npmjs.com › package › eslint-plugin-react
eslint-plugin-react - npm
This plugin exports a recommended configuration that enforces React good practices. To enable this configuration use the extends property in your .eslintrc config file:
      » npm install eslint-plugin-react
    
Published   Apr 03, 2025
Version   7.37.5
Author   Yannick Croissant
🌐
Medium
allalmohamedlamine.medium.com › eslint-flat-config-and-new-system-an-ultimate-deep-dive-2023-46aa151cbf2b
Eslint flat config and new system an ultimate deep dive 2023 | by Mohamed Lamine Allal | Medium
November 27, 2023 - The goals and design choices when making flat config (Eslint team) What changed between the old and the new and what to look-up for ... Packcages no more strings. Now we import all. And we can add things better · Custom parsers and parser options (mostly the same, but better) [no you import, object config] Plugins and their loading and their config, and the naming and the rules
Find elsewhere
🌐
ESLint
eslint.org › docs › latest › extend › plugin-migration-flat-config
Plugin Migration to Flat Config - ESLint - Pluggable JavaScript Linter
If your plugin is exporting configs that refer back to your plugin, then you’ll need to update your configs to flat config format. As part of the migration, you’ll need to reference your plugin directly in the plugins key.
🌐
ESLint
eslint.org › docs › latest › use › configure › configuration-files
Configuration Files - ESLint - Pluggable JavaScript Linter
You can put your ESLint project configuration in a configuration file. You can include built-in rules, how you want them enforced, plugins with custom rules, shareable configurations, which files you want rules to apply to, and more.
🌐
GitHub
microsoft.github.io › rnx-kit › docs › tools › eslint-plugin
eslint-plugin | React Native Developer Tools
This ESLint plugin exports multiple configurations. For instance, to use the recommended configuration, you can re-export it in your flat config like below:
🌐
Reddit
reddit.com › r/reactjs › what eslint rules you recommend?
r/reactjs on Reddit: What eslint rules you recommend?
February 21, 2025 -

Hey all, I am in the process of creating my own eslint version 9 set of rules with a flat config for the first time and I am wondering what you guys are using or recommending as a must have?

I use Typescript with React so thought to definitely include eslint-plugin-react and typescript-eslint. What else? I saw there is sonar eslint too but this one seems not so popular?

Do you have any "gems" that are not enabled by default or not popular but still a great addition?

I also see that many rules can be customized a bit, do you recommend that or rather not?

Really curious and interested about your experience on this, thanks!

🌐
Reddit
reddit.com › r/reactjs › what's the best eslint.config.mjs for a react + typescript project with eslint/prettier/husky?
r/reactjs on Reddit: What's the best eslint.config.mjs for a react + typescript project with eslint/prettier/husky?
April 29, 2024 -

I follow along the bulletproof-react repo from github and tried to setup my project nearly the same way this best practice project does.

Unfortunately, eslint changed their config syntax to flat configs. I feel stupid to ask but can someone help me converting the bulletproof-react eslintr.js file to a eslint.config.mjs one? Or could you recommend any other ressources to see how you'd set up great linting rules for react typescript projects in 2024?

Would appreciate your help

🌐
npm
npmjs.com › package › eslint-plugin-react-hooks
eslint-plugin-react-hooks - npm
// eslint.config.js import reactHooks from 'eslint-plugin-react-hooks'; import { defineConfig } from 'eslint/config'; export default defineConfig([ reactHooks.configs.flat['recommended-latest'], ]); If you are still using ESLint below 9.0.0, the recommended preset can also be used to enable all recommended rules.
      » npm install eslint-plugin-react-hooks
    
Published   Oct 24, 2025
Version   7.0.1
Homepage   https://react.dev/
🌐
Nx
nx.dev › recipes › tips-n-tricks › flat-config
Switching to ESLint's Flat Config Format | Nx
It will also convert the base .eslintrc.json and .eslintignore. Section titled “Correctness and best practices” · The purpose of this generator is to create a flat config that works the same way as the original JSON config did.
🌐
npm
npmjs.com › package › @eslint-react › eslint-plugin
@eslint-react/eslint-plugin - npm
no-deprecated Enable all rules that disallow deprecated React APIs with "error" severity. ... disable-conflict-eslint-plugin-react Disable rules in eslint-plugin-react that conflict with rules in our plugins.
      » npm install @eslint-react/eslint-plugin
    
Published   Feb 14, 2026
Version   2.13.0
Author   Rel1cx
🌐
Medium
medium.com › @contactmanoharbatra › eslint-and-prettier-configuration-f0259ebeb58b
Eslint and Prettier configuration | by Manohar Batra | Medium
September 10, 2025 - In your Vite React project root, run: (sometimes it comes by default when you have installed new app/plugins but you can validate) below screenshot is from package.json file when I created new vite react project ... npm install eslint eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y eslint-plugin-import --save-dev
🌐
Medium
medium.com › @1608naman › a-flat-attempt-at-the-eslint-flat-config-393005212d67
A Flat Attempt at the ESLint Flat Config | by Naman Dhingra | Medium
September 28, 2024 - Even though eslint-config-airbnb-base uses CommonJS and require.resolve, FlatCompat can handle it because it internally uses the old ESLintRC loader system, which is capable of loading configurations in various formats (JSON, YAML, JS, CommonJS). It then translates the loaded config into the new flat config format. The @eslint/compat package offers functions to fix compatibility issues with plugins and rules that haven't been updated for ESLint 9.