Skip to content

Instantly share code, notes, and snippets.

@jon-hotaisle
Created July 17, 2025 22:15
Show Gist options
  • Save jon-hotaisle/9dd8078df6abb3e8e7821bbf013b6594 to your computer and use it in GitHub Desktop.
Save jon-hotaisle/9dd8078df6abb3e8e7821bbf013b6594 to your computer and use it in GitHub Desktop.
Struggling with eslint flat file configuration for a react/vite project? This one works pretty well for me.
// bun add --dev @eslint/js eslint-config-prettier eslint-plugin-import \
// eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-unused-imports \
// eslint eslint-plugin-promise eslint-plugin-react-refresh globals prettier
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import configPrettier from 'eslint-config-prettier';
import pluginImport from 'eslint-plugin-import';
import pluginReact from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import pluginUnusedImports from 'eslint-plugin-unused-imports';
import { globalIgnores } from 'eslint/config';
import pluginPromise from 'eslint-plugin-promise';
import reactRefresh from 'eslint-plugin-react-refresh';
import globals from 'globals';
export default tseslint.config(
globalIgnores(['node_modules/', 'dist/', 'example/', '*.d.ts', 'types/', '**/*.d.ts', 'src/routeTree.gen.ts']),
js.configs.recommended,
...tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
{
files: ['**/*.{ts,tsx}'],
plugins: {
'@typescript-eslint': tseslint.plugin,
'unused-imports': pluginUnusedImports,
import: pluginImport,
promise: pluginPromise,
react: pluginReact,
},
languageOptions: {
ecmaVersion: 'latest',
globals: globals.browser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
// React hooks rules
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
// React rules
'react/react-in-jsx-scope': 'off',
'react/jsx-uses-react': 'off',
'react/prop-types': 'off',
'react/jsx-no-undef': 'error',
'react/jsx-no-duplicate-props': ['error', { ignoreCase: true }],
'react/no-unknown-property': 'error',
'react/self-closing-comp': 'warn',
'react/jsx-curly-brace-presence': ['warn', { props: 'never', children: 'never' }],
'react/jsx-no-constructed-context-values': 'warn',
// TypeScript rules
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/await-thenable': 'warn',
'@typescript-eslint/no-floating-promises': 'warn',
'@typescript-eslint/require-await': 'warn',
// Unused imports rules
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'unused-imports/no-unused-imports': 'error',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
// Import rules
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
'newlines-between': 'always',
alphabetize: { order: 'asc', caseInsensitive: true },
},
],
'no-duplicate-imports': 'warn',
},
settings: {
react: {
version: 'detect',
runtime: 'automatic', // For React 17+ JSX transform
},
},
},
// Apply prettier config last to override formatting rules
configPrettier,
);
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment