Implementing ESLint in a React TypeScript Project: A Step-by-Step Guide

Repo: https://github.com/tramhuuducvn/react-web-practice

What is the problem?

In a project where numerous contributors employ diverse coding styles, maintaining consistency becomes challenging. Adopting a unified coding style convention is essential to ensure the source code remains coherent and manageable.

What is ESLint?

1. Linter 🔍

Let's take a quick look at linters before diving into ESLint concept.

Linter is a software tool used during software development to examine source code and detect syntax errors, bad syntax, or other problems programmers may encounter in their source code.

2. ESLint

A popular open-source JavaScript linting tool that helps developers identify and fix code errors, enforce coding conventions, and maintain consistent code styles. ESLint provides several benefits that can greatly enhance our development process:

  • Consistency: ESLint enforces coding conventions and style guidelines, ensuring consistent code formatting and structure across the project. This leads to improved readability and maintainability.
  • Error Prevention: By catching common programming mistakes and enforcing best practices, ESLint helps prevent errors and reduces bugs in the codebase.
  • Continuous Integration: ESLint can be integrated into continuous integration (CI) pipelines, enabling automated code quality checks and ensuring that code contributions meet the defined standards before merging.
  • Customization Capabilities: ESLint allows you to customize rules and configurations to fit your project's specific needs, including adding rules from plugins or extended rule sets.

Basic usage

In this article, it is assumed that you have already known how to init a React Project with TypeScript. At the moment, I am using Node.js version v18.19.0 and npm version 10.2.3 to init my project.

1. Install ⚙️

Use npm

npm install --save-dev eslint prettier eslint-config-prettier eslint-plugin-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser

Use yarn

yarn add --dev eslint prettier eslint-config-prettier eslint-plugin-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser
  • eslint - A useful linting tool that guarantees developers adhere to standard coding conventions.
  • prettier - Simply put, it beautifies the source code.
  • eslint-config-prettier - Helps avoid conflict between eslint and prettier configurations.
  • eslint-plugin-prettier - Integrates a few prettier rules into ESLint.
  • @typescript-eslint/eslint-plugin - Provides additional rules specific to TypeScript.
  • @typescript-eslint/parser - Parser allows ESLint to analyze TypeScript code and catch errors.

2. Configurations 🛠️🛠️🛠️

2.1 Add new file .eslintrc:

  "root": true,
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint", "prettier", "react-hooks"],
  "extends": [
  "ignorePatterns": ["node_modules/*"],
  "rules": {
    "@typescript-eslint/no-explicit-any": "warn",
    "@typescript-eslint/no-unused-vars": ["warn", { "vars": "all" }],
    "react-hooks/exhaustive-deps": "warn",
    "no-console": ["warn", { "allow": ["info", "warn", "error"] }],
    "no-return-await": "off",
    "@typescript-eslint/return-await": "error",
    "prettier/prettier": [
        "printWidth": 120,
        "useTabs": false,
        "tabWidth": 4,
        "trailingComma": "none",
        "semi": true,
        "singleQuote": false,
        "bracketSpacing": true,
        "arrowParens": "always",
        "jsxSingleQuote": false,
        "bracketSameLine": false,
        "endOfLine": "lf"

2.2 Add new file .prettierrc:

  "printWidth": 120, // max 120 chars in line, code is easy to read
  "useTabs": false, // use spaces instead of tabs
  "tabWidth": 4, // "visual width" of of the "tab"
  "trailingComma": "none", // add trailing commas in objects, arrays, etc.
  "semi": true, // add ; when needed
  "singleQuote": false, // '' for stings instead of ""
  "bracketSpacing": true, // import { some } ... instead of import {some} ...
  "arrowParens": "always", // braces even for single param in arrow functions (a) => { }
  "jsxSingleQuote": false, // "" for react props, like in html
  "bracketSameLine": false, // pretty JSX
  "endOfLine": "lf", // 'lf' for linux, 'crlf' for windows, we need to use 'lf' for git

2.3 Add new scripts to file package.json:

"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject",
  // additions scripts here
  "lint": "eslint src --ext .ts,.tsx",
  "lint-fix": "eslint src --fix --ext .ts,.tsx"

By executing the command yarn lint from your terminal, you can analyze code in all file .ts and .tsx. This command will perform a code analysis and provide feedback on any issues found in the TypeScript files.

By executing the command yarn lint-fix from your terminal, you can automatically fix your code in all files .ts and .tsx according to the specified configuration. This command will apply the necessary fixes to your code, resolving any issues detected by the linter.

2.4 Integrates VSCode extension: ESLint and Prettier.

ESLint: It highlights any issues with a yellow underline, providing warnings and suggestions to improve your code quality.

Prettier: Automatically formats your code to ensure consistent and aesthetically pleasing formatting.

Pre-Commit with Husky 🛡️🛡️🛡️

Install Husky 🐶

Husky enhances your commits and more woof!
Automatically lint your commit messages, code, and run tests upon committing or pushing.

Install it:

# use yarn
yarn add --dev husky
# or use npm
npm install --save-dev husky

And then run npx husky init After the file .husky/pre-commit was generated, add some desired commands you want to run before commit. Example:

#  file .husky/pre-commit
yarn lint
yarn test

Install Lint-staged

Run linters against staged git files and don't let 🐞 slip into your code base!

Install it:

# use yarn
yarn add --dev lint-staged
# or use npm
npm install --save-dev lint-staged

Add some config to package.json:

"lint-staged": {
    "*.tsx": [
        "yarn lint",
        "yarn lint-fix"
    "*.ts": [
        "yarn lint",
        "yarn lint-fix"

The pre-commit hook suggests using yarn lint-staged instead of yarn lint-fix.
yarn lint-staged focuses on fixing only the files you have recently changed, leaving the rest of your code untouched.

Continuous Integration 🚀🚀🚀

name: Test Build React App
    branches: ["main"]

    runs-on: ubuntu-latest
        node-version: [18.x, 20.x]

    - uses: actions/checkout@v3

    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
        node-version: ${{ matrix.node-version }}
    - name: Test & Build
      run: |
            yarn install --frozen-lockfile
            yarn lint --max-warnings=0
            yarn test
            yarn build


  1. Setup dự án Node.js với TypeScript ESLint Prettier (duthanhduoc.com)
  2. Overview | typescript-eslint
  3. Giữ cho code sạch đẹp với ESlint! (viblo.asia)
  4. Rules of Hooks – React (reactjs.org)
  5. Hãy sử dụng ESLint cho dự án của bạn! (viblo.asia)
  6. Escaping the relative import path hell, in Javascript
  7. Nâng cao chất lượng code và hiệu quả làm việc nhóm với Husky, Lint-Staged, CommitLint

All Rights Reserved

Let's register a Viblo Account to get more interesting posts.