Skip to content
Swizec Teller - a geek with a

Javascript debugging [slightly] beyond console.log


My favourite tool for javascript debugging is console.log.

I mean, I love console.log. If I ever get a programming tattoo, it's going to be console.log or some variation thereof. Simple to use, works every time, and every programming language I've used since I was 9 has had some variation of it.

Pascal acting up? Not sure what's going on? writeln

Python being silly? print

C acting funny? printf

CSS weird? border: 1px solid red

HTML messing with you? Nah, Chrome's element inspector.

But as much as I love console.log, sometimes it just does not do. Sure, if you have a proper test suite console.log is always enough. But you don't always have a proper test suite.

Let me explain.

When you want to understand what's going on and where exactly a piece of code goes wrong, you do something like this.

var do_something = function (arg1) {
console.log("got into function", arg1);
var foo = get_my_foo(arg1);
console.log("foo changed?", foo);
return foo;

Not the prettiest. But it works. You can tell what's going on.

You know for certain the function was called, what the argument value was, and you know the value of foo when it returns.

Perfect for calling the code once. But what if it's part of a list building mechanism? (thing) {
var label = do_something(thing);

Wellp, now you've got a bunch of console output to look through. Annoying, but manageable. You can still tell which argument produces which output.

But we're stretching the limits of console.log here.

Now what if somebody does this?, function (thing) {
var label = do_something(thing);

Wow, that's annoying. Your do_something function is called asynchronously. The output is all jumbled up!

Very annoying. But you can map input to output in your mind. They're both printed right next to each other.

It's just harder because you have to read the whole output every time and can't jump to the line you're interested in. The problem is ALWAYS with just one of the elements. Obviously.

Wow, we're really stretching that console.log. Let's break it.

var do_something = function (arg1, callback) {
console.log("got into function", arg1);
var foo = get_my_foo(arg1);
setTimeout(function () {
console.log("foo changed?", foo);
}, 100);
};, function (thing) {
do_something(thing, function (label) {

You wouldn't just spray setTimeouts in your code like that. But now you have an asynchronous function. Maybe it's an Angular watch, you're responding to a promise, or something.

Point is, all of your console.log outputs are now jumbled up and useless. Something like this:

got into function, foo1 got into function, foo3 foo changed?, yes got into
function, foo2 foo changed?, no got into function, foo4 got into function, foo5
foo changed?, yes foo changed?, no foo changed?, yes

Wow, talk about useless!

When faced with a situation like this, I would start adding alert()s to my code. It stops execution and lets you look at the output in a particular moment.

But it blocks the entire browser, you can't look around much, and clicking all those pop ups is annoying as hell. Especially once you've found the culprit, but can't just refresh the page.

alert() disables Cmd+R because it steals focus from the window. You have to get to the end of the loop before you can stop it.


A few weeks ago I stumbled onto a better way through someone's throwaway comment. debugger;

It. Is. Magic.

Instead of that second print statement, console.log("foo changed?", foo), we'd put debugger;. When Chrome, and other modern browsers?, sees that statement, it stops.

But it doesn't just stop. It gives you a debugger.

The debugger, initial view
The debugger, initial view

You can't see it in the screenshot, but even GIFs are stopped. A moment ago that Santa was dancing, now everything is in "Holy shit, he's debugging!" mode.

The code that triggered debugger; is in the middle. A bunch of inspection tools are on the right. On top of the screen is an "I'm done now, please continue" button.

But more importantly, the console is in current scope! You can do whatever you want.

Console is in current scope
Console is in current scope

And once you've found the culprit, you can just refresh the page. No waiting for all the alert()s to show up.

Now, I'm not going to stop using console.log any time soon. But knowing about debugger has made my life easier many times.

I only wish I'd known about it sooner.

Did you enjoy this article?

Published on January 14th, 2015 in Apache Hadoop, Cascading Style Sheets, Debugging, HTML, JavaScript, Technical

Learned something new?
Want to become a high value JavaScript expert?

Here's how it works ๐Ÿ‘‡

Leave your email and I'll send you an Interactive Modern JavaScript Cheatsheet ๐Ÿ“–right away. After that you'll get thoughtfully written emails every week about React, JavaScript, and your career. Lessons learned over my 20 years in the industry working with companies ranging from tiny startups to Fortune5 behemoths.

Start with an interactive cheatsheet ๐Ÿ“–

Then get thoughtful letters ๐Ÿ’Œ on mindsets, tactics, and technical skills for your career.

"Man, love your simple writing! Yours is the only email I open from marketers and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. ๐Ÿ‘Œ"

~ Ashish Kumar

Join over 10,000 engineers just like you already improving their careers with my letters, workshops, courses, and talks. โœŒ๏ธ

Have a burning question that you think I can answer?ย I don't have all of the answers, but I have some! Hit me up on twitter or book a 30min ama for in-depth help.

Ready to Stop copy pasting D3 examples and create data visualizations of your own? ย Learn how to build scalable dataviz components your whole team can understand with React for Data Visualization

Curious about Serverless and the modern backend? Check out Serverless Handbook, modern backend for the frontend engineer.

Ready to learn how it all fits together and build a modern webapp from scratch? Learn how to launch a webapp and make your first ๐Ÿ’ฐ on the side with ServerlessReact.Dev

Want to brush up on your modern JavaScript syntax?ย Check out my interactive cheatsheet:

By the way, just in case no one has told you it yet today: I love and appreciate you for who you areย โค๏ธ

Created bySwizecwith โค๏ธ