DEV Community

Ajmal Hasan
Ajmal Hasan

Posted on

React Native ESLint 9 Setup: Complete Guide with VSCode Integration, Husky Pre-commit Hooks, Prettier, and CI/CD

πŸ“¦ Install All Dependencies

# Core ESLint dependencies
yarn add --dev eslint @eslint/js globals typescript-eslint

# React and React Native plugins
yarn add --dev eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-react-native

# Prettier integration
yarn add --dev prettier eslint-config-prettier

# Husky and lint-staged for pre-commit hooks
yarn add --dev husky lint-staged

# Additional helpful tools
yarn add --dev @types/node
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ File Creation (Step by Step)

1. Create ESLint Configuration

File: eslint.config.mjs

import js from '@eslint/js';
import globals from 'globals';
import tseslint from 'typescript-eslint';
import pluginReact from 'eslint-plugin-react';
import pluginReactHooks from 'eslint-plugin-react-hooks';
import pluginReactNative from 'eslint-plugin-react-native';

export default [
  {
    ignores: ['node_modules/**', 'android/**', 'ios/**', 'build/**', 'dist/**']
  },
  js.configs.recommended,
  ...tseslint.configs.recommended,
  pluginReact.configs.flat.recommended,
  {
    files: ['**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node,
        __DEV__: 'readonly',
        __dirname: 'readonly',
        __filename: 'readonly',
      },
      ecmaVersion: 'latest',
      sourceType: 'module',
      parserOptions: {
        ecmaFeatures: { jsx: true },
      },
    },
    plugins: {
      'react-hooks': pluginReactHooks,
      'react-native': pluginReactNative,
    },
    rules: {
      // React Native
      'react-native/no-unused-styles': 'error',
      'react-native/split-platform-components': 'error',
      'react-native/no-inline-styles': 'warn',
      'react-native/no-color-literals': 'warn',
      'react-native/no-single-element-style-arrays': 'error',

      // React Hooks
      'react-hooks/rules-of-hooks': 'error',
      'react-hooks/exhaustive-deps': 'off', // Disabled for ESLint 9 compatibility

      // React
      'react/react-in-jsx-scope': 'off',
      'react/prop-types': 'off',
      'react/display-name': 'off',

      // General
      'no-console': 'warn',
      'no-debugger': 'error',
      'no-unused-vars': 'off',
      'prefer-const': 'error',
      'no-var': 'error',
      'no-duplicate-imports': 'error',
      'max-lines': ['warn', { max: 300, skipBlankLines: true }],
    },
    settings: {
      react: { version: 'detect' },
    },
  },
];
Enter fullscreen mode Exit fullscreen mode

2. Create Prettier Configuration

File: .prettierrc.js

module.exports = {
  semi: true,
  singleQuote: true,
  tabWidth: 2,
  trailingComma: 'all',
  printWidth: 100,
  bracketSpacing: true,
  arrowParens: 'avoid',
};
Enter fullscreen mode Exit fullscreen mode

3. Create Prettier Ignore

File: .prettierignore

node_modules
android
ios
build
dist
coverage
*.snap
*.md
*.json
*.lock
*.log
.DS_Store
eslint.config.mjs
Enter fullscreen mode Exit fullscreen mode

4. Update Package.json Scripts

Add to package.json:

{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "lint:check": "eslint . --max-warnings 0",
    "prettier": "prettier --write .",
    "prettier:check": "prettier --check .",
    "format": "prettier --write . && eslint . --fix",
    "prepare": "husky install"
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Setup Husky Pre-commit Hooks

# Initialize husky
yarn prepare

# Add pre-commit hook
npx husky add .husky/pre-commit "npx lint-staged"

# Add pre-push hook (optional)
npx husky add .husky/pre-push "yarn lint:check"
Enter fullscreen mode Exit fullscreen mode

6. Create VSCode Settings

File: .vscode/settings.json

{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "explicit"
  },
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],
  "eslint.workingDirectories": ["."],
  "typescript.preferences.organizeImportsIgnoreCase": false,
  "typescript.preferences.includePackageJsonAutoImports": "on",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}
Enter fullscreen mode Exit fullscreen mode

7. Create VSCode Extensions Recommendations

File: .vscode/extensions.json

{
  "recommendations": [
    "esbenp.prettier-vscode",
    "dbaeumer.vscode-eslint",
    "ms-vscode.vscode-typescript-next",
    "bradlc.vscode-tailwindcss"
  ]
}
Enter fullscreen mode Exit fullscreen mode

8. Create GitHub Actions Workflow

File: .github/workflows/lint.yml

name: Code Quality

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'yarn'
      - run: yarn install --frozen-lockfile
      - run: yarn lint:check
      - run: yarn prettier:check
Enter fullscreen mode Exit fullscreen mode

⚑ Quick Setup Commands

# 1. Install everything
yarn add --dev eslint @eslint/js globals typescript-eslint eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-react-native prettier eslint-config-prettier husky lint-staged @types/node

# 2. Initialize husky
yarn prepare

# 3. Setup pre-commit hooks
npx husky add .husky/pre-commit "npx lint-staged"
npx husky add .husky/pre-push "yarn lint:check"

# 4. Run initial format
yarn format
Enter fullscreen mode Exit fullscreen mode

🎯 VSCode Integration Features

  • Auto-fix on save: ESLint fixes applied automatically
  • Format on save: Prettier formatting on file save
  • Import organization: Auto-organize imports on save
  • Real-time linting: Inline error/warning indicators
  • Quick fixes: Ctrl/Cmd+. for fix suggestions

πŸ“‹ Essential VSCode Extensions

Install these extensions for full functionality:

  • ESLint (dbaeumer.vscode-eslint)
  • Prettier (esbenp.prettier-vscode)
  • TypeScript Importer (pmneo.tsimporter)

πŸ”§ Usage

  • Lint all files: yarn lint
  • Fix auto-fixable issues: yarn lint:fix
  • Check for any issues: yarn lint:check
  • Format all files: yarn prettier
  • Format and fix: yarn format

⚠️ Known Issues

  • react-hooks/exhaustive-deps disabled due to ESLint 9 compatibility
  • Will be re-enabled when plugin updates for ESLint 9

πŸš€ Post-Setup

  1. Delete any old .eslintrc.* files
  2. Restart VSCode for settings to take effect
  3. Run yarn format to format existing code
  4. Commit changes to trigger pre-commit hooks

This setup provides a complete, production-ready linting environment with VSCode integration and automated quality checks.

Top comments (0)