Artikel schließen


Console spec in depth

Until now our blog has been a serene and pleasant place. As of today, however, we’ve unleashed our developers and opened up our blog to the subject of black coding magic.

Welcome to the dark side.

The Chrome DevTools console is our go to tool for debugging javascript code in browser.
It’s API itself has been non-standard for the longest time. Nevertheless almost all browser vendors implemented some form of developer console.
The Developer Tools Working Group proposed a standardised logging API in 2013.
In 2014 the The Web Hypertext Application Technology Working Group (WHATWG) took over. Their efforts became a living standard in january of 2016. It also has its own Twitter account.
Although all of the following examples are tailored for Chrome most of it should also work in other browsers. (Thats the fun of having a standard, isn’t it?)

Let’s dive into the standard and see what the console can do.

Basic logging

If you’re anything like us you’ve probably used console.log(…data) in your javascript code.
It’s a nice and convenient way to print (i.e. log) data to the browser console.
Complex data (Array, Object, etc.) will be transformed to an displayable implementation specific representation.

Internally console.log(…data) uses the consoles Logger function with a logLevel of ‘log’. Log levels define which visual style the console will pick to display the data.

var user = {name: 'Mr. X', id: 4872, image: {src: 'some/source/4872.jpg', size: {x: 500, y: 500}}}


The spec calls this an “implementation specific representation”. In this case that means: The objects tree structure is extendable by clicking the little caret in front of it.

Note that you can pass one or more arguments to all logging functions. The console will print them all. This can be super helpful to provide context when logging variables or when logging multiple values.

console.log('currentUser: ', user)

console.log() multiple args

console.log(user.name, user.image.size)

console.log() multiple args 2

String formatting and colors

Logging also supports printing formatted syntax. If the first argument is a string and contains any format specifiers the output will be printed formatted.

console.log('User "%s" (Id: %d) has this image: %o', user.name, user.id, user.image

console.log() formatted
Supported format specifiers are:

  • %s: String (toString())
  • %d, %i: Integer (parseInt())
  • %f: Float (parseFloat())
  • %o, %O: “Implementation-specific representation” (expandable Objects and Arrays)

There is also a kind of weird format specifier called %c, which probably stands for something like CSS. The standard says: “TODO: process %c”.
We’ll investigate how it behaves in Chrome.

%c will use the provided value as the style attribute for any following “element” until there is a new %c-specifier with a new value.
You could leverage this behaviour to add colours to your output.

var cStyle = {red: 'color: red;', bold: 'font-weight: 700;', clear: ''}
  'User %c"%s"%c (Id: %d) has this image: %o',
  cStyle.red + cStyle.bold, // first %c
  user.name, // %s
  cStyle.clear, // second %c
  user.id, // %d
  user.image // %o

console.log() styled
Since this syntax is not very convenient people also made libraries to make this process easier.

Log levels

As mentioned above the internal Logger function supports multiple log levels. These are: log, info, warn and error.
They differ in their visual representation. You can invoke the Logger for different log levels using their respective functions.

console.log(…data) or it’s alias console.debug(…data) › ‘log’

console.info(…data) › ‘info’

console.warn(…data) › ‘warn’

console.error(…data) › ‘error’

Tabular data

It is also possible to log tabular data in the console. Simply throw an array or object at the function and it’ll do its best to display it as table.

You can use the second parameter to pass an array of fields that you wan’t to display.

var people = [{name: 'Marie', age: 26, id: 0},{name: 'Hans', age: 30, id: 1},{name: 'Franz', age: 34, id: 2},{name: 'Susann', age: 31, id: 3}]
console.table(people, ['name', 'age'])


It should fall back to logging if tabular display is not possible.


Sometimes it is important to know why and how a specific function was invoked. You can use console.trace(…data) to output a stack trace next to the supplied logging data.



From time to time it might be useful to count how often certain code is called. console.count(label) makes this easy.
Everytime it is called the console will increment the counter associated with that label.



The label will be cast to a string (at least in Chrome). Therefore console.count(‘a,b’) and console.count([‘a’, ‘b’]) are equivalent.


If you’re logging errors from your code logging is conditional most of the time anyway.
You can assert that a condition is true and otherwise log the error with console.assert(condition, …data).

var expectedUserId = 4700
console.assert(user.id === expectedUserId, 'user.id was expected to be', expectedUserId, 'but is', user.id)


The standard says that the data should be passed to the Logger function with log level error. Chrome also prints the stack trace and doesn’t accept formatting.


When logging multiple statements the console can get clogged quite easily.
You can group multiple logs into neat “implementation specific representation” dropdown tree structures. This works on multiple levels. The standard doesn’t contain much information (yet) so again here’s how it works in Chrome.
console.group(…data) starts a group. Every log entry will be put inside that group until console.groupEnd() is called.
The data passed to group() will be logged as the groups title.

console.group('entering group', 1)
console.log('log entry in group 1')
console.group('entering group', 2)
console.log('log entry in group 2')
console.log('another log entry in group 2')
console.log('another log entry in group 1')


To display the group collapsed by default use console.groupCollapsed(…data) to start a group instead.


The console standard also includes it’s very own stopwatch. You can use console.time(label) to start a timer and console.timeEnd(label) to stop the time and log the result. This is extremely useful for measuring performance.

 // stuff happens



We’ll just cite the WHATWG standard here:

If possible for the environment, clear the console. Otherwise, do nothing.

In Chromes console, window.clear() is an alias for console.clear(). Therefore you’re your fine to just call clear().


Non standard features

There are some non standard features in Chrome that might be useful so we’ll list them here.

Dir vs. log

While Chromes “implementation specific representation” prints out a tree structure for most javascript Objects that is not always the case. The most notable exceptions are DOM nodes, arrays and regular expressions. The console.dir(data) function allows to print that tree structure nevertheless.


console.log() DOM node


console.dir() DOM node

console.log([1, 2, 3])

console.log() array

console.dir([1, 2, 3])

console.dir() array


console.log() RegExp


console.dir() RegExp

Unfortunately this does not work for strings and numbers.
You can also (try) to force “xml like” printing behaviour by using console.dirxml(data) instead.


To start and stop recording a profile in Chrome DevTools from code you can use console.profile(label) and console.profileEnd(label).

Timeline marker

To add a marker to the DevTools timeline you can use console.timeStamp(label).


To get the current memory usage of the environment you can use console.memory.
Since this is just a property on the console object there is no direct printing.



Bottom line

Use the console, Luke.