beginner15 min read·Updated Dec 2024Expert reviewed
Linting & Formatting (ESLint, Prettier)
ESLint catches bugs and enforces code quality; Prettier enforces formatting. They solve different problems and work together. A properly configured lint + format setup runs automatically on save, on commit, and in CI — and eliminates entire classes of review comments.
ESLint is a static analysis tool that finds problems in your JavaScript/TypeScript. It reads your code without running it and reports violations of configurable rules.
What ESLint catches:
Actual bugs: unused variables, unreachable code, missing await, == vs ===
Code quality: complexity, naming conventions, import order
Security: eval(), dangerouslySetInnerHTML misuse
React-specific: missing dependency arrays in hooks, key prop violations
ESLint v9 introduced a new "flat config" format. This is what new projects should use:
// eslint.config.mjsimport js from '@eslint/js';import tseslint from 'typescript-eslint';import reactPlugin from 'eslint-plugin-react';import reactHooks from 'eslint-plugin-react-hooks';export default [ js.configs.recommended, ...tseslint.configs.recommended
ESLint rule severities
'off' or 0 — disabled'warn' or 1 — violation shown as warning (CI can still pass)'error' or 2 — violation shown as error (CI fails)
Use 'error' for bugs and security issues. Use 'warn' for style suggestions you want to migrate toward. Don't leave 'warn' rules forever — they accumulate and become noise.
Prettier reformats your code to a consistent style. The key insight: Prettier removes all formatting decisions. There's no "tabs vs spaces" debate — Prettier decides and enforces.
Prettier handles: indentation, quotes (single/double), semicolons, trailing commas, line length, bracket spacing, arrow function parens.
Prettier does NOT handle: code logic, variable names, import order — that's ESLint.
npx prettier --write src/**/*.ts # format all TypeScript filesnpx prettier --check src/**/*.ts # check without writing (CI mode)
Prettier + ESLint integration
They overlap on some rules (quotes, semicolons). The solution: disable ESLint's formatting rules and let Prettier handle them.
npm install -D eslint-config-prettier
// eslint.config.mjs — add prettier at the end (overrides conflicting rules)import prettier from 'eslint-config-prettier';export default [ ...tseslint.configs.recommended, // ... your rules prettier, // must be last — disables ESLint formatting rules];
Autofix on save in your editor: VS Code: "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" } + Prettier format on save.
Use eslint --fix in lint-staged: automatically fixes fixable issues (avoids trivial "fix trailing comma" commits).
Start with recommended configs then add project-specific rules. Don't write rules from scratch.
Pin ESLint and Prettier versions — formatting changes between Prettier minor versions can cause mass reformatting commits if different team members run different versions.