ESLint Catches the Bugs Code Review Misses
A single assignment inside an if-condition deletes user accounts and throws no error. ESLint catches that class of bug at keystroke speed, not in production, and removes the cognitive churn of style arguments from code review so teams spend their attention on logic and architecture instead.
ESLint parses source into an AST and walks every node against configurable rules, catching mistakes like accidental assignments inside conditionals, unreachable code after return, and unused variables the moment they're typed. It eliminates style debates—tabs versus spaces, semicolons or not—by hardening those decisions into automated checks that run in the editor and at commit time.
TypeScript support comes through @typescript-eslint, which adds type-aware rules that flag explicit any, unsafe assertions, and non-null assertion abuse. Pairing ESLint with Prettier splits the work: ESLint owns code correctness and best practices, Prettier owns formatting, and eslint-config-prettier shuts off the overlapping rules.
A git hook setup with husky and lint-staged blocks commits that fail linting, scanning only staged files to keep the feedback loop fast. Flat config, the default in ESLint 9+, replaces inheritance chains with arrays, making it obvious where every rule originates.
ESLint's value is not just error detection but social: it removes an entire category of low-stakes, high-friction arguments from code review, letting teams reserve their attention for design and logic.
The flat config format solves a real discoverability problem—when rules come through multiple layers of extends, developers often can't tell why a rule is on or off, which erodes trust in the tool.
Pairing ESLint with Prettier is now the de facto standard, but the division of labor is still misunderstood; many teams duplicate formatting rules in ESLint and then fight the resulting conflicts.