GMT+1
Berlin

More Than Just log. Expanding the Power of the JavaScript console

Published on ·
By

Every JavaScript developer knows and loves console.log(). It’s our reliable companion in the world of debugging, allowing us to quickly check a variable's value or confirm that our code reached a specific point.

But what if I told you that console is a whole arsenal of tools, not just a simple notepad? There are many more functions available that can make your debugging and performance analysis cleaner, faster, and more efficient.

We developers use console.log() to output operational information. However, the console function is more than just a debugging tool. Large companies have long realized its potential as a channel for hidden communication with developer visitors, posting security warnings, advertising, or even job listings. If you're interested in how giants like Facebook and NYTimes actually use the console for these purposes, be sure to read my previous article: "From Scary Stories to Job Postings. Hidden Content on Popular Websites". Here, we'll focus on how the extended functions of the console object can make your daily debugging work much more effective.

In this article, we'll delve into the 10 secret capabilities of the console object that will help you become a debugging master.

#1 Different Message Levels for Visual Debugging 🐞

Are you tired of an endless stream of identical log messages? The console API allows you to assign different log levels to messages. While all methods function identically according to the specification, their visual display and filtering are handled very differently by browser engines.

Method Log Level Visual Cue in Firefox (Gecko) Visual Cue in Chrome (Chromium) Filtering Behavior
console.log() Log Plain text. Plain text. Firefox: Separate filter toggle. Chrome: Often grouped with 'Info' or 'Default'.
console.info() Info Small 'i' icon Plain text. Firefox: Separate filter toggle. Chrome: Used as the primary filter level for most general messages.
console.warn() Warning Message on a yellow background with triangle icon Message on a yellow background with triangle icon Always filterable by a dedicated 'Warnings' toggle.
console.error() Error Message on a red background with an error icon Message on a red background with an error icon Always filterable by a dedicated 'Errors' toggle.

Why console.info() still matters:

The key benefit is filtering and semantic clarity. The crucial difference is in the implementation:

Using console.info() still adds semantic clarity to your code, indicating that the message is about the application's state or progress, and it guarantees proper segregation for developers using browsers like Firefox.

Example

The following code is executed when this page loads. To see these different message levels and icons in action, open your browser's Developer Console (usually by pressing F12 or Ctrl+Shift+I):

console.log('This is a simple log.');
console.info('Initialization process complete. (Used for filtering)');
console.warn('Warning! The variable "user" is undefined.');
console.error('Critical Error: Failed to connect to API!');

Once the console is open, explore the available filter settings ("All", "Info", "Log", etc.) to see how your specific browser groups these entries. You will find that your ability to filter log vs. info messages depends entirely on the browser's developer tools implementation.

#2 Stylish Console console.log() with CSS 💅

Want to highlight important messages? You can use the %c substitution string and pass a CSS string as the second argument to style the text.

console.log(
  "%cIMPORTANT MESSAGE",
  "color: white; background: #222b00; font-size: 16px; padding: 5px; border-radius: 5px;"
);

This is great for branding your console or highlighting critically important data during development.

#3 ASCII Art with Template Literals ✨

If you want to make a big impression, such as a recruitment message or a custom logo, nothing beats ASCII art. The easiest way to output multi-line art without using escape characters (\n) is by leveraging Template Literals (strings enclosed in backticks `).

console.log(`
  /\\_/\\
 ( o.o )
  > ^ <
Welcome, developer!
`);

This method is quick, clean, and ensures your complex visual elements render correctly as distinct, multi-line messages in the console.

For Your Reference: Want to add more flair to your console or HTML content? I've created a complete developer cheat sheet with the names, decimal codes, and hex codes for dozens of useful symbols, including all major Currency Signs, Typography Marks, and more. Access the full HTML Entities Reference List here.

#4 Tabular Data Presentation with console.table() 📊

If you're working with arrays of objects or just objects with many properties, console.table() is your best friend. It displays data as a neat, interactive table, which is much easier to read than scrolling through dozens of collapsed objects.

const users = [
  { id: 1, name: 'John', age: 30 },
  { id: 2, name: 'Mike', age: 24 },
  { id: 3, name: 'Alice', age: 45 }
];

console.table(users);
// Outputs a table with columns (index), id, name, age

You can even specify which columns to display:

console.table(users, ['name', 'age']);

#5 Grouping Messages with console.group() and console.groupEnd() 📦

When debugging a complex loop or a function that is called many times, your console output can quickly become a mess. Use grouping to create nested, collapsible blocks to maintain order.

console.log('Start of Main Process');

console.group('Processing User Data (ID: 42)');
console.log('Loading profile...');
console.warn('Email address missing.');

console.groupCollapsed('Request Details'); // Starts a collapsed group
console.log('Method: POST');
console.log('Payload: { ... }');
console.groupEnd();

console.log('Save completed.');
console.groupEnd(); // Returns to the outer level

console.log('Process finished.');

#6 Performance Measurement with console.time() and console.timeEnd()

To measure how long a specific block of code takes to execute, use built-in timers. This is indispensable for micro-optimizations and identifying bottlenecks in your code.

console.time('heavy_loop');

for (let i = 0; i < 1000000; i++) {
  // Execute some "heavy" code
}

console.timeEnd('heavy_loop');
// Output: heavy_loop: 12.345 ms

This is great for branding your console or highlighting critically important data during development.

#7 Stack Trace with console.trace() 👣

When you need to understand exactly where a particular function was called from, console.trace() is essential. It outputs a stack trace that shows the entire path from the start of execution to the current line.

function one() {
  two();
}

function two() {
  three();
}

function three() {
  // Shows that the function 'three' was called from 'two',
  // and 'two' from 'one'
  console.trace('Call from function three');
}

one();

This is critical when debugging complex systems with deep nesting or when working with frameworks where you don't always control the chain of calls.

#8 Conditional Check with console.assert()

If you only want to output a message if a condition is false, use console.assert(). This is essentially an assertion statement for the console, helping you control invariants (conditions that should always be true).

const inventoryCount = 5;

// Will output an error only if inventoryCount is NOT greater than 10
console.assert(inventoryCount > 10, {
    inventoryCount,
    message: 'Inventory too low! Restocking required!'
});

const isLoggedIn = true;
// Will output nothing, as the condition is true
console.assert(isLoggedIn, 'User is not authenticated.');

If the first expression is false, console.assert() will output an error message ("Assertion failed") and a stack trace. If true, nothing happens, and your console stays clean.

#9 Object Inspection with console.dir() 🔍

While console.log() attempts to show DOM elements or complex objects in the most convenient (sometimes browser-specific) view, console.dir() always outputs an interactive, hierarchical list of the properties of the specified JavaScript object.

This is especially useful for inspecting DOM elements when you want to see their pure JavaScript properties, rather than just the HTML representation.

const myElement = document.getElementById('header');

console.log(myElement); // Shows the HTML representation <header id="header">...</header>
console.dir(myElement); // Shows the property tree of the JS object with methods, prototypes, etc.

Most modern browsers automatically render a full URL (e.g., https://tovstonos.com) as a clickable link in the console output. However, you can use the substitution method to create visually distinct areas of your message, which is powerful for announcements or errors.

The key is to use two or more %c specifiers to apply different styling to different parts of the message, with the last style applying to the substituted link (%s).

Technique: Two-Tone Styling (Achieving Your Result)

To create the dual-color block effect seen in your console, you use one style for the introductory text and a second style for the link's background.

let link = 'https://tovstonos.com';

console.log(
  '%cProfessional Website Maintenance available here:%c%s',
  // Style 1: Applied to the descriptive text
  'color: #abc837; font-weight: bold; background: #222b00; padding: 15px 5px 15px 15px;',
  // Style 2: Applied to the substituted link (%s)
  'color: blue; background: #abc837; padding: 15px 15px 15px 5px;', 
  link
);

Analysis and Rationale for Using %s

Feature Rationale Why %s is Essential
Visual Separation The primary benefit in your environment - it creates two side-by-side boxes of different colors. Only two separate arguments (one before the second %c and one after) can achieve this hard color break.
Text Styling You can give the introductory text a dark, dramatic background while giving the link a bright, contrasting background. The %s ensures the URL is treated as the second styled block.
Code Flexibility The URL is a variable, making the announcement reusable for different links. This allows the injection of a dynamic link variable.

Important Note on Link Color: As you observed, even with the second %c applied, the browser/terminal's core link rules still enforce the final link color (black/blue underline). The styling you control is the box-model (background, padding), which is highly effective for visual emphasis.

developer debugging code on a multi monitor setup

Conclusion

console.log() is the foundation, but a true JavaScript master uses the full range of tools offered by the console object. Moving beyond simple string output to using tables, timers, and stack tracing will make your life as a developer much easier and your code analysis clearer.

Start implementing these methods today, and you'll notice how much your debugging process improves! 🛠

Which communication tool
is best for you?