Everything you need to debug front-end JavaScript is already in your browser. This guide covers the four tools that solve nearly every bug, in the order you should reach for them.
1. The console#
Open DevTools with F12 and check the Console tab first. If your page does nothing, the reason is usually sitting there in red.
Logging well is a skill. Label your logs:
console.log(user); // which of the six logs is this?
console.log("user after fetch:", user); // much better
console.table(users); // arrays of objects as a grid
console.error("Save failed", error); // red, with a stack trace
console.warn("Missing id, skipping");Two more that pay for themselves:
console.log({ user, total, isValid }); // logs names AND values
console.time("render");
renderList(items);
console.timeEnd("render"); // render: 42ms2. Breakpoints#
Logging tells you what a value was. A breakpoint lets you look at everything at that moment.
- Open the Sources tab
- Find your file and click a line number — it turns blue
- Trigger the code
- Execution pauses, and you can hover any variable to see its value
You can also pause from code:
function calculateTotal(items) {
debugger; // pauses here when DevTools is open
return items.reduce((sum, i) => sum + i.price, 0);
}Remember to remove it before shipping.
3. Stepping through#
Once paused, four controls matter:
- Resume — carry on until the next breakpoint
- Step over — run this line, do not go inside functions it calls
- Step into — go inside the function on this line
- Step out — finish the current function and come back up
Watch the Scope panel while you step. The moment a variable holds something you did not expect, you have found the bug.
Conditional breakpoints#
Debugging item 400 of a loop? Right-click the line number, choose “Add conditional breakpoint”, and enter something like item.id === 400. It pauses only then.
4. The Network tab#
When the problem is data rather than logic:
- Status — 404 means a wrong URL, 401/403 means authentication, 500 means the server broke
- Response — what actually came back. Often not the shape you assumed.
- Headers — check
Content-Typeand what you sent - Payload — confirm your request body is what you think it is
Remember that fetch does not throw on a 404 — see the Fetch API guide.
Inspecting elements#
Right-click anything and choose Inspect. From there you can edit HTML live, toggle CSS rules on and off, and use the “Event Listeners” panel to see exactly what is attached to an element — useful when a click does nothing or fires twice.
Which tool for which bug#
| Symptom | Start with |
|---|---|
| Page does nothing | Console — look for a red error |
| Wrong value on screen | Labelled console.log around the calculation |
| Complicated logic gone wrong | Breakpoint and step through |
| Data missing or wrong shape | Network tab, Response |
| Styling looks wrong | Elements panel — see why is my CSS not working |
| Click handler does nothing | Elements → Event Listeners |
Questions people ask#
My breakpoint never triggers
Either that code is not running, or you set it in a different copy of the file — check whether a bundler is serving a transformed version. The Sources tree shows which file is actually loaded.
Should I use console.log or a debugger?
Both. Logging is faster for a quick check; breakpoints are far better when you do not yet know which value is wrong.
How do I debug on my phone?
Connect the device and use remote debugging — Chrome DevTools for Android, Safari Web Inspector for iOS. Both give you the full console for the page on the phone.