Skip to Content
Course content

218: Linting with ESLint

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I was reviewing a pull request for a junior dev who had written a complex conditional to handle user permissions. Everything looked fine at a glance, but when we hit production, the app started letting guest users access the admin dashboard. It took me nearly two hours of staring at the code to realize they'd written if (user.role = 'admin') instead of if (user.role === 'admin'). They weren't checking if the user was an admin; they were accidentally assigning the admin role to every single person who hit that line of code.

It was a tiny typo, but a catastrophic one. The worst part? A linter would have flagged that in milliseconds. That's why I don't view ESLint as some annoying "style police" tool—I view it as a safety net that catches the stupid mistakes we all make when we're tired or rushing.

Setting Up Your Project Guardrails

At its core, ESLint is a static analysis tool. It reads your code without actually running it and looks for patterns that are known to be problematic. To get started, you don't want to manually write every single rule from scratch—that would be a nightmare. Instead, we usually initialize a config file using npm init @eslint/config.

This process generates a configuration file (usually .eslintrc.json or eslint.config.js in newer versions). This file is essentially the "law of the land" for your project. If you're working on a team, this ensures that whether I'm writing the code or you are, it looks and behaves consistently. I personally prefer using a shared config like eslint-config-airbnb-base or the recommended defaults, because arguing over whether to use single or double quotes in a meeting is a waste of everyone's time.

Distinguishing Style from Logic

When you start digging into the rules, you'll notice they generally fall into two buckets: stylistic preferences and logic errors. Stylistic rules are things like indent or quotes. While these make the code easier to read, they aren't going to crash your server. Logic rules, however, are critical. Rules like no-undef (which stops you from using a variable that hasn't been declared) or no-unreachable (which flags code after a return statement) save you from hours of debugging.

// ESLint would flag these immediately:
const x = 10;
if (x == 10) { // Warning: eqeqeq (use === instead)
  console.log("Match");
}

const user = { name: "Dev" };
console.log(user.namme); // Error: no-undef (namme is not defined)

I always tell my mentees: don't fight the linter. If it's complaining, it's usually because you're doing something that could potentially bite you later. If you absolutely must bypass a rule for a very specific edge case, you can use a comment like /* eslint-disable-line */, but use that sparingly. If your code is littered with disable comments, you're not using a linter—you're just silencing a warning.

Automating the Cleanup

The real magic happens when you stop running the linter via the command line and integrate it directly into your IDE. When you see those red squiggly lines under your code in real-time, you fix the mistake before you even finish the thought.

Furthermore, most stylistic issues can be handled automatically. Running eslint --fix will go through your files and automatically swap those double quotes for single ones or add missing semicolons. I usually pair ESLint with Prettier for the formatting side of things, letting Prettier handle the "look" and ESLint handle the "correctness." It's a powerful combination that lets you focus on solving the actual problem rather than worrying about where the curly braces go.




📋 Practical Task

Fixing the Buggy Order Processor

You've been handed a piece of legacy code for an e-commerce order processor. It is riddled with "smells" and potential bugs that a linter would normally catch. Your task is to manually "lint" this code by fixing the following issues:

  • Change all loose equality checks (==) to strict equality (===).
  • Find and remove the unused variable that is declared but never used.
  • Fix the accidental assignment inside the if statement (similar to the anecdote in the lesson).
  • Replace the outdated var declarations with let or const.

function processOrder(order) {
  var status = 'pending';
  var internalTrackingId = 'TRK-12345'; // This is never used
  var discountApplied = false;

  if (order.total == 0) {
    return 'Free Order';
  }

  // BUG: This is assigning 'shipped' to order.status instead of comparing it
  if (order.status = 'shipped') {
    return 'Order already sent';
  }

  if (discountApplied == false) {
    console.log("No discount found");
  }

  return 'Order processed successfully';
}
Rating
0 0

There are no comments for now.

to be the first to leave a comment.