← Back to blog

Article

React ESLint Setup

Install ESLint

Install ESLint

$ yarn add --dev eslint prettier

1. Install ESLint CLI

$ yarn add --dev eslint-cli

2. [Setup ESLint]

$ yarn run eslint --init
yarn run v1.22.19
$ /Users/xxx/workspace/yyy/zzz/node_modules/.bin/eslint --init
You can also run this command directly using 'npm init @eslint/config'.
Need to install the following packages:
  @eslint/create-config@0.4.5
Ok to proceed? (y) y
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ How would you like to define a style for your project? · guide
✔ Which style guide do you want to follow? · airbnb
✔ What format do you want your config file to be in? · JavaScript
Checking peerDependencies of eslint-config-airbnb@latest
The config that you've selected requires the following dependencies:
...

3. Downloaded Packages

diff --git a/package.json b/package.json
index 5abcf3a8..31ad26aa 100644
--- a/package.json
+++ b/package.json
@@ -3,26 +3,43 @@
     "type": "module",
     "scripts": {
         "dev": "vite",
-        "build": "vite build && vite build --ssr"
+        "serve": "vite preview",
+        "build": "vite build && vite build --ssr",
+        "lint": "eslint resources/js --ext .js,.jsx,.ts,.tsx",
+        "lint:fix": "eslint resources/js --ext .js,.jsx,.ts,.tsx --fix",
+        "format": "prettier --write resources/js"
     },
     "devDependencies": {
-        "@headlessui/react": "^1.4.2",
-        "@inertiajs/react": "^1.0.0",
         "@tailwindcss/forms": "^0.5.3",
-        "@vitejs/plugin-react": "^3.0.0",
         "autoprefixer": "^10.4.12",
-        "axios": "^1.1.2",
-        "laravel-vite-plugin": "^0.7.5",
+        "eslint": "^7.32.0 || ^8.2.0",
+        "eslint-config-airbnb": "^19.0.4",
+        "eslint-config-prettier": "^8.8.0",
+        "eslint-config-react-app": "^7.0.1",
+        "eslint-plugin-import": "^2.27.5",
+        "eslint-plugin-jsx-a11y": "^6.7.1",
+        "eslint-plugin-prettier": "^4.2.1",
+        "eslint-plugin-react": "^7.28.0",
+        "eslint-plugin-react-hooks": "^4.3.0",
         "postcss": "^8.4.18",
-        "react": "^18.2.0",
-        "react-dom": "^18.2.0",
+        "prettier": "^2.8.8",
         "tailwindcss": "^3.2.1",
-        "vite": "^4.0.0"
+        "vite-plugin-eslint": "^1.8.1"
     },
     "dependencies": {
         "@emotion/react": "^11.11.1",
         "@emotion/styled": "^11.11.0",
+        "@headlessui/react": "^1.7.15",
+        "@inertiajs/react": "^1.0.9",
+        "@mui/icons-material": "^5.11.16",
         "@mui/material": "^5.13.6",
-        "mui-image": "^1.0.7"
+        "@vitejs/plugin-react": "^4.0.1",
+        "axios": "^1.4.0",
+        "laravel-vite-plugin": "^0.7.8",
+        "mui-image": "^1.0.7",
+        "prop-types": "^15.8.1",
+        "react": "^18.2.0",
+        "react-dom": "^18.2.0",
+        "vite": "^4.3.9"
     }
}

4. ESLint & prettier Config

  1. .eslintrc.cjs
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
  },
  extends: [
    'airbnb',
    'eslint:recommended',
    'plugin:prettier/recommended',
    'plugin:react/recommended',
  ],
  settings: {
    react: {
      version: 'detect',
    },
    'import/resolver': {
      node: {
        path: ['node_modules', 'resources/js'],
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    },
  },
  overrides: [
    {
      env: {
        node: true,
      },
      files: ['.eslintrc.{js,cjs}'],
      parserOptions: {
        sourceType: 'script',
      },
    },
  ],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
    },
  },
  plugins: ['react', 'import', 'prettier'],
  rules: {
    'no-unused-vars': 'warn',
    'import/extensions': 'off',
    'import/no-unresolved': 'warn',
    'import/no-extraneous-dependencies': 'warn',
    'react/jsx-props-no-spreading': 'warn',
    'react/prop-types': 'warn',
    'react/require-default-props': 'warn',
  },
}
  1. .prettierrc
{
  "semi": true,
  "tabWidth": 4,
  "printWidth": 100,
  "singleQuote": true,
  "trailingComma": "none"
}

5. Vite Config

This is for SSR build.

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
import eslint from 'vite-plugin-eslint';

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.jsx',
            ssr: 'resources/js/ssr.jsx',
            refresh: true
        }),
        react(),
+       eslint({
+           include: ['/resources/js/**/*.jsx', '/public/assets/*'],
+           exclude: ['node_modules/**']
+       })
    ],
    resolve: {
        alias: {
            '@': '/resources/js',
            '@assets': '/public/assets'
        },
+       extensions: ['.js', '.jsx', '.ts', '.tsx']
    }
});

Discussion

Profile picture

Full-Stack Engineer

Yerin Hong

Building products end-to-end across frontend, mobile, backend, and product UX.

Full-stack engineer and generalist. I design, build, and debug products with a bias for clean UX and practical engineering.

© 2026 Yerin Hong

Built with Gatsby