Skip to content

ESLint and Prettier: Code Quality Automation for JavaScript

DodaTech Updated 2026-06-22 6 min read

In this tutorial, you'll learn ESLint and Prettier setup including rules configuration, plugin integration, format-on-save, and integrating linters into CI/CD pipelines for consistent code quality.

Why Linting and Formatting Matter

Code reviews should focus on logic, not formatting. Inconsistent indentation, missing semicolons, and unused variables waste reviewer time and create friction in pull requests. ESLint catches bugs and enforces code quality rules. Prettier enforces consistent formatting automatically. Together, they eliminate an entire class of code review comments.

By the end of this guide, you will configure ESLint and Prettier for any JavaScript project, set up format-on-save, and integrate linting into CI/CD.

What are ESLint and Prettier?

ESLint is a pluggable linter for JavaScript and TypeScript. It analyzes code for potential errors, enforces coding standards, and can auto-fix certain issues. Prettier is an opinionated code formatter that parses code and reprints it with consistent style.

flowchart LR
  A[Source Code] --> B[ESLint]
  A --> C[Prettier]
  B --> D[Errors Found?]
  D -->|Yes| E[Fix or Report]
  D -->|No| F[Pass]
  C --> G[Format Code]
  G --> H[Consistent Style]
  E --> I[CI Fails]
  F --> J[CI Passes]

ESLint Setup

npm init @eslint/config

Or install manually:

npm install --save-dev eslint
npx eslint --init

Expected Output

$ npx eslint --init
You can also run this command directly using 'npm init @eslint/config'.
Need to install the following packages:
  @eslint/create-config
Ok to proceed? (y) y

? How would you like to use ESLint? ...
? What type of modules does your project use? JavaScript modules (import/export)
? Which framework does your project use? React
? Does your project use TypeScript? Yes
? Where does your code run? Browser
? What format do you want your config file to be in? JSON

ESLint Configuration

{
  "env": {
    "browser": true,
    "es2021": true,
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:"@typescript"-eslint/recommended]
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": ["react", "@typescript-eslint"],
  "rules": {
    "indent": ["error", 2],
    "linebreak-style": ["error", "unix"],
    "quotes": ["error", "single"],
    "semi": ["error", "always"],
    "no-unused-vars": "warn",
    "no-console": "warn",
    "react/react-in-jsx-scope": "off"
  }
}

Running ESLint

# Lint a file
npx eslint src/index.js

# Lint with auto-fix
npx eslint src/index.js --fix

# Lint entire project
npx eslint src/ --ext .js,.jsx,.ts,.tsx

Expected Output

$ npx eslint src/index.js

/home/user/project/src/index.js
  5:10  warning  'unusedVar' is defined but never used  no-unused-vars
  8:2   error    Expected indentation of 2 spaces but found 4  indent
  9:18  error    Strings must use singlequote  quotes

2 problems (2 errors, 1 warning)
1 error and 0 warnings potentially fixable with the `--fix` option.

Prettier Setup

npm install --save-dev prettier

Prettier Configuration

Create .prettierrc:

{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 100,
  "bracketSpacing": true,
  "arrowParens": "always",
  "endOfLine": "lf"
}

Running Prettier

# Check formatting
npx prettier --check src/

# Format files
npx prettier --write src/

# Format with specific file types
npx prettier --write "src/**/*.{js,ts,jsx,tsx,css,json}"

Expected Output

$ npx prettier --check src/
Checking formatting...
src/index.js
src/utils.js
Code style issues found in 2 files. Run Prettier with --write to fix.

$ npx prettier --write src/
src/index.js 48ms
src/utils.js 32ms

ESLint and Prettier Together

ESLint and Prettier can conflict. Use eslint-config-prettier to disable ESLint rules that conflict with Prettier.

npm install --save-dev eslint-config-prettier

Update .eslintrc.json:

{
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:"@typescript"-eslint/recommended",
    "prettier]
  ]
}

The prettier config must be last in extends to override conflicting rules.

Format-on-Save in VS Code

{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "editor.formatOnSave": true,
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

Git Hooks with Husky

Prevent unformatted code from being committed.

npm install --save-dev husky lint-staged
npx husky init

Lint-Staged Configuration

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "eslint --fix",
      "prettier --write]
    ],
    "*.{css,json,md}": [
      "prettier --write]
    ]
  }
}

Husky Pre-commit Hook

# .husky/pre-commit
npx lint-staged

Expected Behavior

When you run git commit, Husky triggers lint-staged, which runs ESLint and Prettier on staged files only. If linting fails, the commit is prevented.

ESLint for TypeScript

npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin
{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "rules": {
    "@typescript-eslint/explicit-function-return-type": "warn",
    "@typescript-eslint/no-explicit-any": "error",
    "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
  }
}

CI/CD Integration

GitHub Actions

# .github/workflows/lint.yml
name: Lint

on: [pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx eslint src/ --max-warnings 0
      - run: npx prettier --check src/

GitLab CI

lint:
  stage: test
  image: node:20
  script:
    - npm ci
    - npx eslint src/ --max-warnings 0
    - npx prettier --check src/

Common Errors

Problem Cause Fix
ESLint and Prettier conflict Both modify same formatting rules Add prettier as the last item in ESLint's extends
<a href="/compiler-design/syntax-analysis/">Parsing</a> error: Unexpected token ESLint not configured for JSX/TypeScript Set parser: @<a href="/programming-languages/typescript/">TypeScript</a>-eslint/parser and enable jsx in parserOptions
Prettier breaks long lines unexpectedly printWidth too small Increase printWidth in .prettierrc
Husky hooks not running .git/hooks path mismatch Run npx husky install
ESLint fix changes too many files Rules too aggressive Use warn instead of error for style rules

Practice Questions

1. What is the purpose of eslint-config-prettier?

It disables ESLint rules that conflict with Prettier's formatting.

2. How do you auto-fix ESLint issues from the command line?

npx eslint --fix <file>.

3. What does lint-staged do in combination with Husky?

It runs linters only on staged files (files about to be committed), preventing unformatted code from entering the Repository.

4. How do you check if Prettier would change any files without actually modifying them?

npx prettier --check src/.

5. What is the purpose of the --max-warnings 0 flag in ESLint CI commands?

It treats warnings as errors, causing CI to fail if any warnings exist.

Challenge

Create a complete ESLint and Prettier setup for a TypeScript + React project. Add Husky pre-commit hooks with lint-staged. Configure ESLint with TypeScript rules, React rules, and import ordering. Add a GitHub Actions workflow that runs linting on every Pull Request.

Real-World Task

Take an existing JavaScript or TypeScript project without linting. Initialize ESLint and Prettier, run the initial fix, and resolve all remaining lint errors. Set up format-on-save in your editor. Configure Husky to prevent unformatted commits. Create a CI workflow that runs the linter on pull requests.

Should I use ESLint or Prettier for formatting?

Use Prettier for formatting and ESLint for code quality rules. Prettier is better at formatting; ESLint is better at catching errors and enforcing conventions.

Can ESLint and Prettier work together?

Yes. Install eslint-config-prettier to disable ESLint rules that conflict with Prettier. Then run Prettier first, followed by ESLint.

Do I need both a linter and a formatter?

Yes, they serve different purposes. ESLint catches bugs like unused variables and potential errors. Prettier ensures consistent formatting. Both are valuable for code quality.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro