# How to Configure Vite ESLint for React Projects: Complete Setup Guide

> Set up Vite ESLint for React projects easily. Follow our guide to integrate official configs, ensuring code quality and smooth development with React Hooks and Fast Refresh.

- Repository: [Vite/vite](https://github.com/vitejs/vite)
- Tags: how-to-guide
- Published: 2026-02-19

---

**To configure Vite ESLint for React, use the flat config preset provided in the official React template at [`packages/create-vite/template-react/eslint.config.js`](https://github.com/vitejs/vite/blob/main/packages/create-vite/template-react/eslint.config.js), which includes React Hooks and Fast Refresh rules, then add a `"lint": "eslint ."` script to your [`package.json`](https://github.com/vitejs/vite/blob/main/package.json) to run checks manually.**

The `vitejs/vite` repository provides a first-class ESLint configuration designed specifically for React projects. Because Vite's dev server does not run linting automatically during development, understanding how to properly configure and invoke ESLint ensures you catch code quality issues before they reach production.

## Default ESLint Configuration in Vite React Templates

When you bootstrap a React project using `npm create vite@latest`, the template includes a minimal [`eslint.config.js`](https://github.com/vitejs/vite/blob/main/eslint.config.js) file located at [`packages/create-vite/template-react/eslint.config.js`](https://github.com/vitejs/vite/blob/main/packages/create-vite/template-react/eslint.config.js). This file uses the modern **flat config** format (`defineConfig` from `eslint/config`) and pre-configures:

- **Core ESLint rules** via `js.configs.recommended` from `@eslint/js`
- **React Hooks validation** via `eslint-plugin-react-hooks`
- **Fast Refresh compatibility** via `eslint-plugin-react-refresh`
- **Browser globals** via `globals.browser`
- **JSX parsing** with ECMAScript 2020 support

```javascript
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{js,jsx}'],
    extends: [
      js.configs.recommended,
      reactHooks.configs.flat.recommended,
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
      parserOptions: {
        ecmaVersion: 'latest',
        ecmaFeatures: { jsx: true },
        sourceType: 'module',
      },
    },
    rules: {
      'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
    },
  },
])

```

## Step-by-Step Setup Guide

### Creating the Project

Generate a new Vite React project using the official template. This ensures you inherit the base [`eslint.config.js`](https://github.com/vitejs/vite/blob/main/eslint.config.js) and peer dependencies:

```bash
npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install

```

### Installing Dependencies

The template's [`package.json`](https://github.com/vitejs/vite/blob/main/package.json) already lists the required dev dependencies: `eslint`, `@eslint/js`, `eslint-plugin-react-hooks`, `eslint-plugin-react-refresh`, `globals`, and `typescript-eslint` (for TypeScript variants). Running `npm install` guarantees the exact versions vetted by the Vite team.

### Adding the Lint Script

Vite does not automatically lint during development. Add a manual script to [`package.json`](https://github.com/vitejs/vite/blob/main/package.json) to run checks on demand or in CI:

```json
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "eslint ."
  }
}

```

Execute `npm run lint` to validate the entire codebase against the configured rules.

## Extending the Base Configuration

### Adding React-Specific Plugins

For stricter React validation, install additional community plugins like `eslint-plugin-react-x` and `eslint-plugin-react-dom`:

```bash
npm install --save-dev eslint-plugin-react-x eslint-plugin-react-dom

```

Extend the base configuration by importing these plugins and adding them to the `extends` array:

```javascript
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{js,jsx}'],
    extends: [
      js.configs.recommended,
      reactHooks.configs.flat.recommended,
      reactRefresh.configs.vite,
      reactX.configs.recommended,
      reactDom.configs.recommended,
    ],
    plugins: { 'react-x': reactX, 'react-dom': reactDom },
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
      parserOptions: {
        ecmaVersion: 'latest',
        ecmaFeatures: { jsx: true },
        sourceType: 'module',
      },
    },
    rules: {
      'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
      'react-x/no-unknown-property': 'error',
    },
  },
])

```

### Enabling Type-Aware Linting

For TypeScript projects, leverage `@typescript-eslint` rules that require type information. The Vite repository's global configuration at [`packages/vite/eslint.config.js`](https://github.com/vitejs/vite/blob/main/packages/vite/eslint.config.js) demonstrates a pattern for conditionally enabling type checking based on the `VSCODE_PID` environment variable.

To implement this in your project, reference your [`tsconfig.json`](https://github.com/vitejs/vite/blob/main/tsconfig.json) in the parser options:

```javascript
import tseslint from 'typescript-eslint'

export default defineConfig([
  {
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      parser: tseslint.parser,
      parserOptions: {
        project: ['./tsconfig.json'],
      },
    },
  },
])

```

Set `VSCODE_PID=1 npm run lint` to activate type-aware rules during local development, or run the lint task directly from VS Code to trigger the enhanced checking.

## Key Configuration Files Reference

| File | Role | Location |
|------|------|----------|
| [`eslint.config.js`](https://github.com/vitejs/vite/blob/main/eslint.config.js) | Default flat config for React templates including hooks and refresh plugins | [`packages/create-vite/template-react/eslint.config.js`](https://github.com/vitejs/vite/blob/main/packages/create-vite/template-react/eslint.config.js) |
| [`eslint.config.js`](https://github.com/vitejs/vite/blob/main/eslint.config.js) | Repository-wide baseline with Node rules, import ordering, and conditional type-checking | [`packages/vite/eslint.config.js`](https://github.com/vitejs/vite/blob/main/packages/vite/eslint.config.js) |
| [`package.json`](https://github.com/vitejs/vite/blob/main/package.json) | Defines ESLint dependencies and the `"lint": "eslint ."` script | [`packages/create-vite/template-react/package.json`](https://github.com/vitejs/vite/blob/main/packages/create-vite/template-react/package.json) |
| [`vite.config.js`](https://github.com/vitejs/vite/blob/main/vite.config.js) | Minimal Vite configuration loading `@vitejs/plugin-react` | [`packages/create-vite/template-react/vite.config.js`](https://github.com/vitejs/vite/blob/main/packages/create-vite/template-react/vite.config.js) |

## Summary

- **Vite provides a ready-made ESLint setup** via the React template at [`packages/create-vite/template-react/eslint.config.js`](https://github.com/vitejs/vite/blob/main/packages/create-vite/template-react/eslint.config.js), using the modern flat config format with React Hooks and Fast Refresh rules pre-configured.
- **Manual execution is required** because Vite's dev server does not lint automatically; add `"lint": "eslint ."` to [`package.json`](https://github.com/vitejs/vite/blob/main/package.json) and run `npm run lint`.
- **Extension is straightforward** using the flat config API—import additional plugins like `eslint-plugin-react-x`, add them to the `extends` array, and customize rules while preserving the base configuration.
- **Type-aware linting** can be enabled for TypeScript projects by referencing [`tsconfig.json`](https://github.com/vitejs/vite/blob/main/tsconfig.json) in `parserOptions.project`, with conditional activation via environment variables as demonstrated in the repository's global config.

## Frequently Asked Questions

### Does Vite automatically lint code during development?

No, Vite's development server does not run ESLint automatically. You must manually invoke linting by adding a script such as `"lint": "eslint ."` to your [`package.json`](https://github.com/vitejs/vite/blob/main/package.json) and running `npm run lint`, or by configuring your IDE to run ESLint on file save.

### How do I add custom ESLint rules to a Vite React project?

Edit the [`eslint.config.js`](https://github.com/vitejs/vite/blob/main/eslint.config.js) file in your project root. Import additional plugins (such as `eslint-plugin-react-x`), add them to the `plugins` object, include their recommended configs in the `extends` array, and define custom rules in the `rules` section. The flat config format allows you to extend the base Vite template configuration while adding project-specific requirements.

### Can I use TypeScript-aware ESLint rules with Vite's default configuration?

Yes. Install `typescript-eslint` and configure the `parserOptions.project` field in your [`eslint.config.js`](https://github.com/vitejs/vite/blob/main/eslint.config.js) to point to your [`tsconfig.json`](https://github.com/vitejs/vite/blob/main/tsconfig.json). The Vite repository demonstrates a pattern where type-aware linting is conditionally enabled based on the `VSCODE_PID` environment variable, allowing you to run heavy type-checking rules during local development while keeping CI linting fast.

### Where does Vite store the default ESLint configuration for React templates?

The default configuration is located at [`packages/create-vite/template-react/eslint.config.js`](https://github.com/vitejs/vite/blob/main/packages/create-vite/template-react/eslint.config.js) in the `vitejs/vite` repository. This file uses the ESLint flat config format and includes pre-configured rules for React Hooks (`eslint-plugin-react-hooks`) and React Fast Refresh (`eslint-plugin-react-refresh`), along with browser globals and recommended ESLint rules.