Debugging JavaScript Applications with Chrome DevTools
Best Practices
Debugging is like detective work.
When your JavaScript application misbehaves, you need the right tools to identify the culprit, trace its actions, and fix the root cause.
Chrome DevTools is your magnifying glass, notebook, and flashlight all in one.
It allows you to step into the shoes of your code, pause it mid-action, and ask: “Why did you do that?”
In this article, we will dive into best practices for debugging JavaScript applications using Chrome DevTools, combining analogies, practical examples, and step-by-step techniques to help you become a debugging master.
Table of Contents
· Table of Contents
· Why Debugging with DevTools Matters
· Opening Chrome DevTools
· Best Practices for Debugging with DevTools
∘ 1. Replace console.log with Breakpoints
∘ 2. Use Conditional Breakpoints
∘ 3. Inspect Call Stack
∘ Example
∘ 4. Monitor Variables with Watch Expressions
∘ 5. Use debugger Statements in Code
∘ 6. Debug Asynchronous Code
∘ 7. Step Through Code Effectively
∘ 8. Leverage Console for Live Testing
∘ 9. Debug Network and API Responses
∘ 10. Use Performance Profiling for Hard-to-Spot Bugs
· Putting It All Together: A Real Example
· Conclusion
Why Debugging with DevTools Matters
Imagine running a factory where machines are producing widgets. Suddenly, some widgets are broken. If you only look at the final product (console logs), you might miss the exact point where the machine went wrong. But if you could pause the machine mid-cycle and inspect the parts, you’d easily spot the fault.
That’s what DevTools offers, runtime inspection rather than just post-mortem analysis.
Opening Chrome DevTools
There are multiple ways to open DevTools:
- Right-click on your page and select Inspect.
- Press
F12orCtrl + Shift + I(Windows/Linux),Cmd + Option + I(Mac). - From Chrome menu: More Tools > Developer Tools.
Once open, you’ll see several panels: Elements, Console, Sources, Network, Performance, Memory, Application, etc.
We’ll focus mainly on Console and Sources for debugging JavaScript.
Best Practices for Debugging with DevTools
1. Replace console.log with Breakpoints
Most developers start with console.log debugging:
function calculateDiscount(price, discount) {
console.log("Price:", price);
console.log("Discount:", discount);
return price - (price * discount);
}
calculateDiscount(100, 0.25);This works for simple cases, but it quickly becomes messy.
Breakpoints are a better magnifying glass.
- Go to the Sources tab.
- Open the JavaScript file.
- Click the line number where you want execution to pause.
Now, when the code runs, it will stop at that line, allowing you to:
- Inspect variables
- Step through the code line by line
- Watch values change in real time
Instead of shouting out numbers while running, you get to freeze the game and walk around the playing field.
2. Use Conditional Breakpoints
Sometimes you don’t want to stop every time a line executes only under certain conditions.
Right-click the line number → Add conditional breakpoint.
Example:
for (let i = 0; i < 10; i++) {
console.log("Iteration:", i);
}Instead of stopping on every loop iteration, you can add a conditional breakpoint like:
i === 5Now DevTools will only pause when i equals 5.
Best Practice: Use conditional breakpoints to avoid “noise” in debugging and to target only suspicious cases.
3. Inspect Call Stack
When execution pauses, check the Call Stack panel on the right side of DevTools.
It shows you how your code arrived at this line, like a breadcrumb trail.
Example
function a() {
b();
}
function b() {
c();
}
function c() {
console.log("Breakpoint here");
}
a();If you set a breakpoint inside c(), the call stack shows:
c → b → aThis helps trace back which function calls led to the error.
4. Monitor Variables with Watch Expressions
Instead of scanning your code for variables, add them to the Watch panel.
Get Adekola Olawale’s stories in your inbox
Join Medium for free to get updates from this writer.
For example:
let cart = [
{ name: "Laptop", price: 1200 },
{ name: "Mouse", price: 25 }
];
let total = cart.reduce((sum, item) => sum + item.price, 0);If you’re unsure why total seems wrong, set a breakpoint and add sum and item.price to the Watch panel.
DevTools will update them every step.
Think of it as attaching a heart-rate monitor to your variables, and you see how they change over time.
5. Use debugger Statements in Code
Instead of relying only on DevTools, you can insert a debugger statement in your code:
function calculateTax(amount) {
debugger; // Chrome pauses here if DevTools is open
return amount * 0.075;
}
calculateTax(200);This automatically triggers a breakpoint when the function runs. It’s like planting a roadblock inside your code.
6. Debug Asynchronous Code
JavaScript often deals with async operations (timeouts, fetch requests, promises).
These can be tricky because execution doesn’t follow a straight line.
Example:
setTimeout(() => {
console.log("This runs later");
}, 2000);
console.log("This runs first");Use Async Call Stack in DevTools (check the right panel) to trace back asynchronous execution.
It shows you not only where the function paused but also which async event scheduled it.
7. Step Through Code Effectively
When paused on a breakpoint, use the toolbar controls:
- ▶️ Resume: Continue execution
- ⏭ Step Over: Run the current line and move on
- ⬇ Step Into: Dive inside the function call
- ⬆ Step Out: Finish current function and return
Best Practice: Use Step Into when you suspect the bug is inside a function, and Step Over when you trust the function.
8. Leverage Console for Live Testing
While paused at a breakpoint, open the Console tab and directly run JavaScript expressions in the current scope.
For example, if paused inside a function with price and discount variables:
price * discountYou’ll get the live computed result.
This is like asking your program questions while it’s frozen.
9. Debug Network and API Responses
Sometimes bugs come not from your logic but from the data you receive.
- Go to the Network tab.
- Click on a request.
- Check the Preview or Response tab.
This ensures your frontend is working with the expected data.
If the response is wrong, you know the bug is upstream in the API.
10. Use Performance Profiling for Hard-to-Spot Bugs
Some bugs don’t crash your app but make it slow.
Go to the Performance tab:
- Click Record, use your app, then stop recording.
- You’ll see flame charts showing CPU usage, paint times, and memory usage.
This helps detect infinite loops, expensive DOM updates, or slow network calls.
Putting It All Together: A Real Example
Let’s say you’re debugging this buggy shopping cart code:
function checkout(cart) {
let total = 0;
cart.forEach(item => {
total += item.prize; // Bug: should be item.price
});
return total;
}
let cart = [
{ name: "Book", price: 15 },
{ name: "Pen", price: 5 }
];
console.log(checkout(cart));- If you just used
console.log, you might only seeNaN. - With DevTools:
- Set a breakpoint at
total += item.prize. - Step through each iteration.
- Inspect
item. - Notice there’s no
prizeproperty, onlyprice.
Bug found and fixed.
Conclusion
Debugging with Chrome DevTools is about more than stopping bugs; it’s about understanding your code deeply.
By using breakpoints, stepping through logic, inspecting variables, and monitoring async behavior, you turn debugging from frustration into a structured investigation.
Next time your JavaScript acts up, remember: don’t just log, investigate. DevTools is your detective toolkit, and with practice, you’ll solve bugs faster and more reliably.








