How to console.log with colors in JavaScript


I’m sure we’re all familiar with console.log() in JavaScript, since it’s the main debugging tool for many developers. But how can we improve our logs with some colors in the console?

Perhaps we’ve also learned about the following:

  • console.info() for informational messages
  • console.error() for errors
  • console.warn() for warnings
  • console.table() for iterable objects

Let’s take this a step further and find how we can apply custom styles to our logs.

Printing to the developer console with %c

We can apply our own styling to a log message by doing two things:

  • Prefixing the message with the %c flag
  • Providing a string of CSS as the second parameter

As a simple example, we can make the log message orange.

console.log("%cLog Message", "color: orange");

You might notice that %c will inject the CSS styles specified in the second argument into that location.

The string of CSS can get pretty long, so I recommend defining the styles separately in an array and joining each element with a semi-colon.

It’s reusable and much cleaner than manually type out the CSS string.

Pro Tip: it’s all about the padding and border-radius.

let baseStyles = [
  "color: #fff",
  "background-color: #444",
  "padding: 2px 4px",
  "border-radius: 2px"
].join(";");
console.log("%cLog Message", baseStyles);

I encourage you to try this out in your console right now, and check out what’s possible.

A Step Further

We can take this a step further and create our own set of logging methods.

This also allows us to avoid typing out the %c flag for every log message.

const Style = {
  base: [
    "color: #fff",
    "background-color: #444",
    "padding: 2px 4px",
    "border-radius: 2px"
  ],
  warning: [
    "color: #eee",
    "background-color: red"
  ],
  success: [
    "background-color: green"
  ]
}
const log = (text, extra = []) => {
  let style = Style.base.join(';') + ';';
  style += extra.join(';'); // Add any additional styles
  console.log(`%c${text}`, style);
}
log("Normal Logs");
log("Warning Logs", Style.warning);
log("Success Logs", Style.success);
Colors in developer console

Printing to the terminal with %s and \x1b

For the terminal, we can use %s and \x1b to print colored logs.

console.log("\x1b[33m%s\x1b[0m", "Log Message"); // yellow text

Notice the %s in the first argument string. This is where the second argument (the string we want to print) will be injected.

The first half of the string (before the %s) is: \x1b[33m.

The second half of the string (after the %s) is: \x1b[0m.

Technically, we can omit the %s and just print the log directly.
console.log("\x1b[33mLog Message\x1b[0m"), but that’s harder to read.

Let’s get a better idea of what’s going on.

Quick Explanation of \x1b

\x1b signals the start of an ANSI escape sequence. \x1b is just a special way of inserting an ESC character into the terminal. This ESC character will be intercepted by the terminal.

The following opening bracket [ signals the start of some function.

In the string above, we see the “functions”: 33m and 0m.

We can think of the numbers as function arguments and m as the function. We are essentially running m(33) and m(0).

code description
\x1b begin escape sequence
[ call a function
0;1 function arguments (0, 1), multiple args are separated by “;”
m function name

m refers to a function called SGR that allows us to inject terminal styling into our logs.

The number(s) corresponds to the specific style.

value description
0 Reset: turn off all attributes
1 Bold (or bright, depending on terminal/user configuration)
3 Italic
4 Underline
30–37 Set text color from the basic color palette of 0–7
38;5;n Set text color to index n in a 256-color palette (e.g. \x1b[38;5;34m)
38;2;r;g;b Set text color to an RGB value (e.g. \x1b[38;2;255;255;255m)
40–47 Set background color
48;5;n Set background color to index n in a 256-color palette
48;2;r;g;b Set background color to an RGB value
90–97 Set text color from the bright color palette of 0–7
100–107 Set background color from the bright color palette of 0–7

In our case, 33 happens to correspond to a yellow text color, so we are setting the terminal color to be yellow.

We can also string together multiple styles by passing in multiple function arguments: \x1b[33;1m (yellow and bold).

However, note that this m(33) function will continue display all subsequent text as yellow.

This is why we need 0m, or m(0), to reset all terminal styles after that log.

A Step Further

Once again, we can take this a step futher to create a set of logging methods using %s and \x1b.

Suppose we have this set of styles that we want to use.

const Log = {
  reset: "\x1b[0m",
  bright: "\x1b[1m",
  dim: "\x1b[2m",
  underscore: "\x1b[4m",
  blink: "\x1b[5m",
  reverse: "\x1b[7m",
  hidden: "\x1b[8m",
  // Foreground (text) colors
  fg: {
    black: "\x1b[30m",
    red: "\x1b[31m",
    green: "\x1b[32m",
    yellow: "\x1b[33m",
    blue: "\x1b[34m",
    magenta: "\x1b[35m",
    cyan: "\x1b[36m",
    white: "\x1b[37m",
    crimson: "\x1b[38m"
  },
  // Background colors
  bg: {
    black: "\x1b[40m",
    red: "\x1b[41m",
    green: "\x1b[42m",
    yellow: "\x1b[43m",
    blue: "\x1b[44m",
    magenta: "\x1b[45m",
    cyan: "\x1b[46m",
    white: "\x1b[47m",
    crimson: "\x1b[48m"
  }
};

We can then define a generic function to use these colors.

const log = (color, text) => {
  console.log(`${color}%s${Log.reset}`, text);
};
log(Log.fg.red, "My text is red");
log(Log.bg.cyan, "My background is cyan");
Colors in terminal