Quick Links
JavaScript developers are familiar with the humble
console.log()
function. Although console logging may appear straightforward, there's much more available within the
console
object. Let's look at how you can enhance your log messages with advanced formatting.
The Basics
Let's recap the most-used console functions:
-
console.log(data, ...args)
data
-
console.info(data, ...args)
console.log()
-
console.error(data ...args)
console.log()
stderr
-
console.warn(data, ...args)
console.error()
Format Specifiers
Developers usually only pass a single argument to the above commands. Nonetheless, they all accept multiple arguments, which are automatically concatenated in the final output.
You can also use arguments with
printf
-compatible format specifiers defined by a string in
data
:
const value = 10;const available = "available";
console.log("There are %d options", value, available);
// Logs "There are 10 options available"
The available format specifiers are as follows:
-
%s
-
%i
-
%f
-
%O
-
%o
-
%c
Support for the last two varies by JavaScript engine. They're available in modern browsers but not necessarily in other execution contexts.
Adding Images
Using the CSS format specifier, it's possible to include images in console output! This works in browsers but won't be supported in CLI environments such as Node.js.
const css = ["background-image: url(https://example.com)",
"background-size: cover",
"height: 100px",
"padding: 15px",
"width: 100px"
];
console.log("%cI'm An Image!", css.join(";"));
We hijack CSS'
background-image
rule to render the image. While it may seem lighthearted, this could have practical use cases if your debugging involves working with images. You can check the images being retrieved without actually emitting them to the page.
Tabulated Output
JavaScript includes built-in support for emitting tabulated data to the console. Use
console.table()
with an array of uniform objects. The column headers will be determined automatically, based on the properties common to each object.
const objects = [{a: 1, x: "a"}, {a: 2, x: "b"}];console.table(objects);
This can be extremely useful when you're working with objects in bulk. Instead of having to iterate an array and call
console.log()
with each item, just use
console.table()
and benefit from the automatically formatted output.
Conditional Output
You can use the
console.assert()
function to condition output on the value of an expression. This reduces the code you need to write compared with prefacing a
console.log()
with an
if
statement.
Your message will only be logged if the expression evaluates to
false
. An expression evaluting to
true
will result in nothing being emitted.
console.assert(true, "I never appear");console.assert(false, "I will be logged");
The
console.assert()
function does not affect runtime. No error will be thrown if the assertion fails; your expression is used solely to determine whether to log to the console.
Message Groups
You can visually group sections of output together with
console.group()
. This will apply an automatic indent to subsequent lines using a predefined number of spaces.
To close the group, call
console.groupEnd()
. This restores the previous indentation.
You may call
console.group()
multiple times before
console.groupEnd()
to create deeply nested output.
console.groupEnd()
reverts the indentation by one step at a time, so you'll need to match the number of
group()
and
groupEnd()
calls before you get back to the default level.
Counters
Use
console.count(label)
to create an internal counter with a given name:
console.count("my-counter");// my-counter: 1
console.count("my-counter");
// my-counter: 2
This gives you a straightforward way to emit incrementing values. You don't have to specify a name - the
default
counter will be used automatically. You can reset counters to 0 using
console.countReset(label)
.
Timers
The console has built-in support for operation timing. Elapsed time is measured in milliseconds and emitted in seconds (e.g. "1.234s"); it's not guaranteed to be high-accuracy.
console.time();// ...some time later...
console.timeEnd();
// Emits the elapsed time ("1.234s")
Timers support optional labels in the same way as counters. This lets you manage multiple timers simultaneously when timing different aspects of your code.
Utility Methods
The
console
object includes several utility methods which help you manage your output.
-
console.clear()
-
console.dir(obj, options)
obj
depth
options
-
console.trace()
There are other non-standardised methods which are engine-dependent. An example is
console.profile()
, which is widely available but with differing implementations. In browsers, it generally invokes high-accuracy profiling to help you diagnose performance issues.
Conclusion
There's much more to JavaScript's console than the basic
console.log()
! Taking the time to learn the available functions can drastically accelerate debugging, particularly when working with complex objects or fast-moving output.
The available features do depend on the JavaScript engine you're working with. Generally, you'll get the most advanced styling from an up-to-date browser, although Node.js also supports most of the techniques we've described here.