cf.completefrontendCode editorOpen lab
THE JAVASCRIPT FIELD GUIDE

Linting with ESLint

Use ESLint as an automatic code proofreader: understand rules, configs, editor squiggles, fix-on-save, and which warnings to treat as errors.

By the end, you can
  • 01
    Explain lint outputRead a rule id, line number, severity, and autofix hint without panic.
  • 02
    Choose rules through configRecognize the shape of an ESLint flat config and common severities.
  • 03
    Wire linting into your editorKnow how VS Code squiggles, quick fixes, and fix-on-save fit together.

What a linter does

A linter is an automatic checker that reads your code and reports likely mistakes before you run the code. ESLint is the most common linter for JavaScript. It can catch a misspelled variable name, a comparison your team has decided to avoid, unreachable code after a return, or a value that was created and then forgotten.

The important word is reads. ESLint usually does not click your page, call your functions, or prove every possible behavior. It parses the file, applies configured rules, and gives you a message with a rule id, a line and column, and a severity: warning or error.

Real-life analogyA linter is a spell-and-grammar checker for code

Before you send a message, spell-check can underline a typo. It does not know what you meant to say, but it catches problems early. ESLint gives your JavaScript the same kind of early warning.

In real life: Red squiggle under a typo
In JavaScript: A lint message under totla
In real life: Grammar rule: use a period
In JavaScript: ESLint rule: use ===
In real life: Autocorrect fixes a safe typo
In JavaScript: --fix changes safe syntax, such as let to const
In real life: Some sentences need a human
In JavaScript: Some bugs need tests and debugging

Where the analogy stops: A spell-checker understands prose only shallowly, and a linter understands code only through its rules. Passing lint is not the same as proving the program is correct.

Earlier lessons gave you tools, strict mode, semicolons, and coding style. Linting combines those habits into feedback you see while you type. npm and package.json get their own lesson later, so for now just recognize commands like npm init @eslint/config@latest and npx eslint as ways to set up and run the checker.

Watch a linter inspect a file
Step 0 of 2Ready
Your turn: follow the blue line

Choose the clean or misspelled version. These results are recorded from ESLint and checked by this lesson's tests.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
console.log(totla);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
Choose the line 2 spelling that ESLint checked

Changing the spelling starts a fresh recorded lint check.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Lint this code: rules report messages

INTERACTIVE

ESLint output is meant to be read like a checklist, not like a scary stack trace. Each message names the rule that spoke. Toggle rules in the playground and notice that rules are independent: the output is the union of the enabled rule results for the selected snippet.

Lint this code
Loose equalityPop out in the code editor (opens in a new tab)JavaScript
if (score == "10") {  console.log("match");}
Recorded lint output2 problems
  1. eqeqeq line 1, column 11 error

    Expected '===' and instead saw '=='.

    Not safely autofixable
  2. no-undef line 1, column 5 error

    'score' is not defined.

    Not safely autofixable
Try it yourself
Snippet:

2 recorded ESLint messages. Each message below shows the rule id, severity, line, column, and whether ESLint has a safe autofix.

Results are recorded from ESLint and checked by this lesson’s tests. The page shows data; it does not bundle ESLint into the browser.

A useful lint message usually answers four questions: what rule fired, where is the code, how serious is it, and can ESLint safely fix it? Rule ids are searchable, so no-undef means “a name was used but never declared,” and prefer-const means “this let never changes.”

Recorded, not live ESLint

This site does not bundle ESLint into the browser because that would make the lesson heavy. The examples store ESLint’s recorded output, and the lesson tests compare every line number, rule id, message, severity, and autofix flag with a real ESLint 9 Linter run.

ESLint rules and configs

RULEBOOK

A rule is one house rule for code. A config is the rulebook ESLint reads before checking files. ESLint 9 uses a flat config file named eslint.config.js by default. A common starting point imports recommended JavaScript rules, then adds project-specific choices.

Real-life analogyRules are house rules; a config is the rulebook

Teams choose habits so everyone can work in the same house without arguing over every little thing. ESLint puts those habits in one repeatable place.

In real life: Take shoes off at the door
In JavaScript: eqeqeq: use === instead of ==
In real life: Quiet hours after 10
In JavaScript: no-console: maybe warn in app code
In real life: The posted list on the fridge
In JavaScript: eslint.config.js

Where the analogy stops: A house rule is enforced by people. ESLint enforces only the rules enabled in its config, and only on files it checks.

eslint.config.jsPop out in the code editor (opens in a new tab)JavaScript
import js from "@eslint/js"; export default [  js.configs.recommended,  {    languageOptions: {      globals: {        document: "readonly",        console: "readonly"      }    },    rules: {      eqeqeq: "error",      "no-unused-vars": "warn"    }  }];

Severities can be written as strings or numbers: off is 0, warn is 1, and error is 2. Warnings are yellow sticky notes: useful, but not always build-breaking. Errors are stop signs. Use errors for bugs or project rules that should fail CI.

Common ESLint config ideas
IdeaWhat it meansBeginner-friendly example
RuleOne named checkno-undef reports names that were never declared
SeverityHow loud the rule iswarn for a nudge, error for a stop sign
Recommended configA preset set of rulesjs.configs.recommended from @eslint/js
GlobalsNames ESLint should treat as already availableBrowser projects often mark document and console readonly; many teams use the globals package
Disable commentA local escape hatch// eslint-disable-next-line no-alert with a clear reason
Use disable comments sparingly

Sometimes a line is intentionally unusual. Prefer a small disable comment near that line, with a short explanation, over turning a rule off for the whole project. The comment is a note to the next person, not a way to hide confusing code.

Fixing on save

STEP THROUGH

Some lint messages are safe to fix mechanically. ESLint calls those fixable. For example, if a variable is declared with let and never reassigned, prefer-const can rewrite it to const without changing the program’s output. Other rules, such as no-undef, usually need a human: ESLint cannot know whether you meant total, totla, or a new variable.

Watch one safe ESLint fix
Step 0 of 2Ready
Your turn: follow the blue line

Step through one real autofix. The lesson stores the output from verifyAndFix, and the tests compare it with ESLint.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
console.log(limit);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

In a terminal, npx eslint . reports problems and npx eslint . --fix asks ESLint to apply safe fixes. The npm lesson later will explain exactly what npx and project scripts do. For now, read the command as “run ESLint on this project.”

Common terminal commandsShell
npm init @eslint/config@latestnpx eslint .npx eslint . --fix

Editor integration

INTERACTIVE

ESLint is most helpful when your editor shows it before you switch to the terminal. In VS Code, install the ESLint extension. It reads the project’s config, underlines problems, offers quick fixes, and can apply safe fixes when you save. Recent VS Code settings use "explicit" for save actions; older examples accepted true.

Fix on save: editor setting
.vscode/settings.jsonJSON
{  "editor.codeActionsOnSave": {    "source.fixAll.eslint": "explicit"  }}
What save can dosafe fixes
let limit = 3;console.log(limit);

Saving can change let limit to const limit because ESLint proved the variable is never reassigned.

Try it yourself

When the VS Code ESLint extension sees this setting, saving the file can apply safe ESLint fixes. Recent VS Code uses explicit; older examples sometimes show true.

Use this setting with the VS Code ESLint extension. ESLint still needs a project config.
VS Code setting for ESLint fix on saveJSON
{  "editor.codeActionsOnSave": {    "source.fixAll.eslint": "explicit"  }}

Editor integration does not replace learning the rule. When a squiggle appears, read the message, look at the line, and decide: accept the quick fix, change the code yourself, or make a deliberate exception. That habit turns linting into coaching instead of noise.

Linter or formatter?

SORT

The previous lesson introduced Prettier formatting. A formatter is a copy editor for layout. It chooses indentation, line wrapping, and other style details so humans stop arguing over them. A linter is more like a proofreader looking for suspicious meaning: unused names, unknown variables, unreachable code, and rules your team chose.

Formatter vs linter
ToolMostly checksTypical result
FormatterHow code is laid outRewrites spaces, line breaks, quotes, and trailing commas
LinterWhether code violates a ruleReports a message; sometimes offers a safe fix
Both togetherTeam consistencyPrettier handles layout, ESLint handles code-quality rules
Linter or formatter?
  • A variable is created but never used
  • Indentation is inconsistent
  • Code uses == where the team wants ===
  • A line is too long to read comfortably
  • A variable is read before it is declared
  • A missing trailing comma in a multiline list
  • An extra semicolon after a statement
Try it yourself
0 of 7 correct

Sort each issue by the tool that usually helps first. Some teams configure overlap, but these are good beginner defaults.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Where you’ll use linting

In a real project, linting appears in three places. First, the editor shows squiggles while you type. Second, a terminal command checks the whole project before you share work. Third, a team may run the same command in CI, which is an automated check before code is merged.

Imagine building a small shopping-cart page. A linter cannot tell you whether the checkout design is good. It can catch that cartTotal was misspelled as cartTtoal, that code after return will never run, or that two object keys use the same name and one silently overwrites the other.

A practical beginner workflow
  1. Write a small piece of code.
  2. Read any ESLint squiggle before running the page.
  3. Apply safe quick fixes, but understand them.
  4. Run npx eslint . before you consider the work done.
  5. If a rule feels wrong, ask whether the config or your code should change.
An autofix keeps the output the samePop out in the code editor (opens in a new tab)JavaScript
const limit = 3;console.log(limit);

Common misconceptions

“If lint passes, the app works.”

Passing lint only means enabled static rules found no problem. You still need to run the code, test behavior, and think.

“Every lint message is a bug.”

Some are style or maintainability warnings. Read the severity and rule id before deciding how urgent it is.

“Autofix means ESLint understands my goal.”

Autofix means the rule author marked a rewrite as safe. It does not mean ESLint knows your product requirement.

“Formatters and linters do the same job.”

They overlap at the edges, but Prettier is mainly layout and ESLint is mainly rule-based code quality.

“Disable comments are harmless.”

They can be correct, but they also hide feedback. Keep them narrow and explain why the exception exists.

Practice: make ESLint useful

5 EXERCISES
Exercise 1 · Warm-upPredict the rule id

Which rule reports the misspelled name in this snippet?

Starter codePop out in the code editor (opens in a new tab)JavaScript
let count = 1;
console.log(cout);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticeFix all problems in a tiny snippet

    Rewrite the snippet so it lints clean with prefer-const, then type what the fixed program prints.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    let total = 1 + 2;
    console.log(total);

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeWrite the rule setting

      In an ESLint config, make strict equality an error.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      import js from "@eslint/js";
      
      export default [
        js.configs.recommended,
        {
          rules: {
            eqeqeq: "error"
          }
        }
      ];

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeSet up fix on save

        Add the VS Code setting from the lesson. What value goes on source.fixAll.eslint?

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeDecide warn or error

          Your team decides that unknown variables should never be merged. Should no-undef be a warning or an error?

          Answer, then press Check. Spacing and letter case don’t matter.

            Quiz: check your understanding

            7 QUESTIONS

            Try each question before opening explanations. Several choices are plausible, because real linting decisions are about tradeoffs.

            Lesson quiz · 7 questionsScore: first tries count
            1. Question 1 of 7What is a linter's main job?

              Choose an answer to see the explanation.

            2. Question 2 of 7Which rule reports this code?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log(totla);

              Choose an answer to see the explanation.

            3. Question 3 of 7In ESLint severities, which setting usually fails a script or CI job?

              Choose an answer to see the explanation.

            4. Question 4 of 7What does this program print after ESLint autofixes prefer-const?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              let limit = 3;
              console.log(limit);

              Choose an answer to see the explanation.

            5. Question 5 of 7Which file name matches ESLint 9's flat config style shown in this lesson?

              Choose an answer to see the explanation.

            6. Question 6 of 7Which tool is most likely to fix inconsistent indentation automatically?

              Choose an answer to see the explanation.

            7. Question 7 of 7Why should inline disable comments be rare?

              Choose an answer to see the explanation.

            Key takeaways

            • A linter reads code before it runs and reports rule violations.
            • ESLint messages include a rule id, severity, line, column, message, and sometimes a safe fix.
            • Configs are rulebooks. In ESLint 9, eslint.config.js is the default flat config file.
            • Use error for stop signs and warn for guidance.
            • Fix on save and editor squiggles make linting part of the writing loop.
            • Formatters handle layout; linters handle rule-based code quality.

            Remember the one-liner.
            A linter is an automatic code proofreader: it catches likely mistakes and team-rule violations before you run the code.

            Up next: Thinking like a developer.

            CompleteFrontend Clear concepts. Working examples.