Sitemap

Debugging JavaScript Applications with Chrome DevTools

Best Practices

Press enter or click to view image in full size

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.

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 F12 or Ctrl + 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 === 5

Now 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 → a

This 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 * discount

You’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 see NaN.
  • With DevTools:
  1. Set a breakpoint at total += item.prize.
  2. Step through each iteration.
  3. Inspect item.
  4. Notice there’s no prize property, only price.

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.