# Debugging with Breakpoints

A debugger pauses your program at a breakpoint, lets you run it one line at a time, and shows every variable's value as you go, in VS Code for Node and in the browser's DevTools for a page, so you can see the line where a value goes wrong.

Apprentice · JavaScript · Software Development · Updated November 1, 2026

## After this lesson you can

- Pause a program at a breakpoint and step through it line by line
- Watch variables in the debugger to find where a value goes wrong

## Key takeaways

- A breakpoint marks a line where the debugger pauses the program. The highlighted line hasn't run yet.
- Step Over runs one line, Step Into goes inside the function on that line, Step Out finishes the function, and Continue runs to the next breakpoint.
- The Variables panel shows every variable's value at the pause. Quotes around a value mean it's a string.
- The Watch panel keeps an eye on any expression you type, such as typeof servings, at every pause.
- The same tools are in VS Code for Node and in the browser's DevTools (the Sources panel) for a page.

The hardest bugs don't stop your program with an error. It runs, and the answer is wrong: a total that's too big, a name that's missing, a game score that never goes up. You can sprinkle `console.log` lines everywhere and run it again and again, and that works. But there's a tool made for this job, the **debugger**, which every professional uses. It pauses your program in the middle, shows you every value, and lets you move forward one line at a time until you see the moment something goes wrong. It's the same tool whether the bug is in a class assignment, a game or an app at work.

## A bug you can't see

This script scales the pancake recipe (it serves 4) for a brunch party: 10 guests plus 2 extra helpings. The number of guests comes from a form, so it arrives as text. Copy it into a file named `party.js`:

```javascript
// party.js: scale the pancake recipe for a brunch party
const recipe = [
  { name: "flour", cups: 2 },
  { name: "milk", cups: 1.5 },
  { name: "sugar", cups: 0.25 },
];
const recipeServes = 4;

function scaleCups(cups, servings) {
  const factor = servings / recipeServes;
  return cups * factor;
}

const guestsTyped = "10"; // typed into a form, so it's text
const extraHelpings = 2;
const servings = guestsTyped + extraHelpings;

for (const item of recipe) {
  console.log(`${item.name}: ${scaleCups(item.cups, servings)} cups`);
}
```

```text
flour: 51 cups
milk: 38.25 cups
sugar: 6.375 cups
```

12 servings should need 6 cups of flour, not 51. Nothing crashed, so there's no error message to read. Somewhere a value is wrong, and you can't see which one by looking at the output.

## Breakpoints: pause the program

Think of a sports replay: you pause on the exact moment of the foul and look at where every player is standing. A **breakpoint** is that pause button for code: a mark on a line that tells the debugger *stop here, before you run this line*.

To set one in VS Code:

1. Open your folder in VS Code and open `party.js`.
2. Move the mouse to the left of the line number of `const factor = servings / recipeServes;` (line 10). A faint red dot appears. Click it, and the dot stays: that's your breakpoint.
3. Start the debugger: **Run > Start Debugging**, or **F5** (on a Mac laptop you may need **fn+F5**). If VS Code asks which debugger to use, choose **Node.js**.

The program runs until it reaches line 10, then pauses. The line is highlighted in yellow. The highlighted line **hasn't run yet**: it's the next one to run. `factor` doesn't have a value yet.

![VS Code paused at a breakpoint on line 10 of party.js: the line is highlighted, and the Variables panel on the left shows servings as "102" in quotes, which reveals it's text](https://www.ask-codey.com/lessons/TODO)

## Look at the values

While the program is paused, the **Run and Debug** view on the left shows what the program knows at this moment:

- **Variables** lists every variable that exists here, with its value. Inside `scaleCups` it shows `cups: 2` and `servings: "102"`.
- **Watch** shows any expression you add. Click the **+** at the top of the Watch panel and type `typeof servings`: it shows `"string"`.
- **Call Stack** shows which function called which to get here: `scaleCups` on top, and below it the line that called it.

Look again at `servings`. Its value has quotes around it, `"102"` (VS Code may show single quotes, `'102'`). Quotes mean it's a string, not a number. `"10" + 2` doesn't add: it joins the text `"10"` and `2` into `"102"`, as you saw in *Types and Converting Between Them*. Then `"102" / 4` turns the text back into a number, `25.5`, and the flour is 2 times 25.5: 51 cups. The bug isn't on the paused line at all. It's on line 16, where `servings` got its value.

**Try it.** Set the breakpoint on line 10, start debugging, and find `servings` in the Variables panel. Then add `typeof servings` and `servings / recipeServes` to Watch. Do they match what you worked out above?

## Step through, one line at a time

When the program is paused, a small toolbar appears at the top of VS Code. Its buttons move the program forward:

| Button | Key in VS Code | What it does |
|---|---|---|
| Continue | F5 | Runs on until the next breakpoint, or to the end |
| Step Over | F10 | Runs the highlighted line, then pauses on the next one |
| Step Into | F11 | If the highlighted line calls a function, goes inside it and pauses on its first line |
| Step Out | Shift+F11 | Runs the rest of the current function and pauses where it was called from |
| Stop | Shift+F5 | Ends the program |

Press **Step Over** once: line 10 runs, `factor` appears in Variables as `25.5`, and line 11 is highlighted. Press **Continue**, and the program pauses at line 10 again, for the milk this time, since `scaleCups` runs once per ingredient.

To find where a value first goes wrong, start earlier. Move the breakpoint to line 14 (`const guestsTyped = "10";`), start again, and press Step Over line by line, watching `servings`. The moment it appears as `"102"` is the moment you've found the bug. When the highlighted line is the `console.log` in the loop, press **Step Into** to go inside `scaleCups`, and **Step Out** to come back.

## The fix

`servings` needs a number before it's added to. `Number()` turns text into a number:

```javascript
const servings = Number(guestsTyped) + extraHelpings;
```

With that line in place, `party.js` prints the right amounts:

```text
flour: 6 cups
milk: 4.5 cups
sugar: 0.75 cups
```

## The same tools in the browser

Code that runs on a web page has a debugger too, in the browser's **DevTools** (developer tools). Here's the same script on a page of its own. Save it as `party.html`:

```html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Brunch Party Scaler</title>
</head>
<body>
  <h1>Brunch Party Scaler</h1>
  <p>Open the DevTools Console to see the shopping list.</p>
  <script>
    const recipe = [{ name: "flour", cups: 2 }, { name: "milk", cups: 1.5 }];
    const recipeServes = 4;
    const guestsTyped = "10";
    const servings = guestsTyped + 2;
    for (const item of recipe) {
      console.log(`${item.name}: ${item.cups * (servings / recipeServes)} cups`);
    }
  </script>
</body>
</html>
```

The page's code goes between `<script>` and `</script>`. To debug it:

1. Open `party.html` in Chrome or Edge (double-click it, or use VS Code's Live Preview).
2. Open DevTools: **F12**, or **Ctrl+Shift+I** (Windows) or **Cmd+Option+I** (Mac). Choose the **Sources** panel and click `party.html` in the list of files on the left.
3. Click the line number of the `for` line. A blue marker appears: that's the breakpoint.
4. Reload the page (**F5** or **Ctrl+R**, **Cmd+R** on a Mac). The script runs again and pauses on your line.

On the right, **Scope** shows the variables (with `servings: "102"`), and **Watch** and **Call Stack** work as in VS Code. The step buttons are the same too, with one difference: **Resume** (Continue) is **F8** here. Firefox has the same tools in its **Debugger** panel.

You can also pause from inside the code: a line that says `debugger;` pauses the program right there whenever DevTools is open, or VS Code is debugging. Delete it when you're done.

**Try it.** Debug `party.html` in your browser, find `"102"` in Scope, then fix the page the way you fixed `party.js` and reload it.

## Check yourself

2 questions to try on the lesson page.

## So what

Every developer meets bugs that don't crash. With a breakpoint, the Variables panel and Step Over, you stop guessing and watch your program work, until the line where a value goes wrong is right in front of you.

## Key terms

- Debugger
- Breakpoint
- [Developer Tools](https://www.ask-codey.com/glossary/developer-tools)
- [Call Stack](https://www.ask-codey.com/glossary/call-stack)

## Cheat sheets

- [Debugging with Breakpoints](https://www.ask-codey.com/cheat-sheets/javascript-debugging-breakpoints-cheat-sheet)

## Related

- [Handling Errors with try, catch and finally](https://www.ask-codey.com/lessons/javascript-errors-try-catch-finally)

Source: https://www.ask-codey.com/lessons/javascript-debugging-breakpoints
