Chrome Devtools Console Commands (2026)
The Chrome DevTools console is one of the most powerful tools in a web developer’s toolkit. Beyond simple console.log(), the console API offers a comprehensive suite of commands that can dramatically improve your debugging workflow. Most developers use maybe five percent of what the console can do. This guide covers the essential Chrome DevTools console commands that professional developers rely on daily, including several that rarely appear in introductory tutorials but save significant time once you know they exist.
Accessing the Console
Open Chrome DevTools by pressing F12, Ctrl+Shift+I (Windows/Linux), or Cmd+Option+I (Mac). Click the Console tab, or press Ctrl+` (backtick) to toggle the console drawer while viewing any other DevTools panel. You can also right-click any element on a page and choose “Inspect” to jump directly to the Elements panel, then switch to Console from there.
One underused tip: open a standalone console window by clicking the three-dot menu in DevTools and selecting “Undock into separate window.” This gives you a full-screen console alongside your app, which is useful on single-monitor setups during long debugging sessions.
Essential Console Output Commands
console.log() and Its Variants
The most commonly used command is console.log(), but the console API provides distinct methods for different logging levels:
// Basic logging
console.log('Application started');
console.info('User logged in successfully');
console.warn('This feature will be deprecated in v2.0');
console.error('Failed to connect to API');
Using the appropriate method matters for more than aesthetics. Each level has a distinct visual style in the console, but more importantly, you can filter by level using the dropdown at the top of the console panel. When an application logs hundreds of messages, being able to show only console.error() calls is the difference between finding a bug in 30 seconds versus 30 minutes.
The console.error() method also automatically captures a stack trace. Every error log includes a clickable link back to the source file and line number, making it far more useful than console.log() for tracking down where something went wrong.
Structured Logging with console.table()
For arrays and objects, console.table() displays data in a readable tabular format:
const users = [
{ id: 1, name: 'Alice', role: 'admin' },
{ id: 2, name: 'Bob', role: 'editor' },
{ id: 3, name: 'Charlie', role: 'viewer' }
];
console.table(users);
This command is particularly useful for inspecting API responses, database query results, or any structured data. You can also specify which columns to display by passing an array of property names as the second argument:
// Only show the name and role columns, not id
console.table(users, ['name', 'role']);
The output is a sortable table, you can click column headers to sort, which makes comparing values across records much faster than reading through an expanded object tree.
console.dir() vs. console.log() for DOM Nodes
When logging a DOM element, console.log() and console.dir() behave differently in ways that matter:
const button = document.querySelector('#submit-btn');
console.log(button); // Shows the HTML element representation
console.dir(button); // Shows the JavaScript object with all properties
If you need to inspect event listeners, style properties, or custom data attributes on a DOM node, use console.dir(). The HTML representation from console.log() is easier to read visually, but the object view from console.dir() exposes the full API surface.
Debugging Commands
console.assert()
Write assertions that only log when a condition is false:
function divide(a, b) {
console.assert(b !== 0, 'Division by zero attempted', { a, b });
return b !== 0 ? a / b : NaN;
}
divide(10, 0);
// Output: Assertion failed: Division by zero attempted {a: 10, b: 0}
This approach keeps your code clean while providing runtime validation during development. Unlike throwing an error, a failed assertion logs to the console and continues execution, useful for catching invalid states that don’t immediately break anything but indicate a logic problem upstream.
console.trace()
When working with complex call stacks, console.trace() prints the full execution path that led to that point:
function innerFunction() {
console.trace('How did we get here?');
}
function middlewareFunction() {
innerFunction();
}
function outerFunction() {
middlewareFunction();
}
outerFunction();
Output will show the complete call chain: innerFunction > middlewareFunction > outerFunction. This is invaluable when a function is called from multiple places in a large codebase and you need to know which code path triggered a particular execution. It’s also useful for tracking down the source of recursive calls gone wrong.
console.count() and console.countReset()
Track how many times a code block executes without manually maintaining counters:
function handleClick() {
console.count('Button clicks');
}
handleClick(); // Button clicks: 1
handleClick(); // Button clicks: 2
handleClick(); // Button clicks: 3
console.countReset('Button clicks');
handleClick(); // Button clicks: 1
This works particularly well for monitoring event handler invocations or loop iterations. If an event fires 47 times when you expected 3, console.count() will surface that immediately. You can use multiple counters simultaneously with different labels.
console.time() and console.timeEnd()
Measure how long synchronous operations take with microsecond precision:
console.time('Array processing');
const result = largeArray
.filter(item => item.active)
.map(item => item.value * 2)
.sort((a, b) => b - a);
console.timeEnd('Array processing');
// Output: Array processing: 12.453 ms
For async operations, wrap the timer around a Promise or use console.timeStamp() to mark points in a performance recording. You can run multiple timers simultaneously with different labels:
console.time('db-query');
console.time('render');
fetchUsers().then(users => {
console.timeEnd('db-query');
renderList(users);
console.timeEnd('render');
});
This gives you independent measurements for each phase without the timers interfering with each other.
The debugger Statement
The most direct way to pause execution is the debugger statement, which triggers a breakpoint when DevTools is open:
function processPayment(amount, currency) {
debugger; // Execution pauses here with DevTools open
const converted = convertCurrency(amount, currency);
return submitTransaction(converted);
}
When execution hits debugger, the Sources panel opens automatically and you can step through code, inspect variable values, and evaluate expressions in the console while execution is paused. This is more reliable than a conditional console.log() for diagnosing issues that only appear with specific inputs.
Advanced Console Techniques
Grouping Output
Organize related console output with collapsible groups:
console.group('User Authentication');
console.log('Checking credentials...');
console.log('Validating token...');
if (tokenValid) {
console.group('Session Setup');
console.log('Creating session');
console.log('Setting cookies');
console.groupEnd();
}
console.groupEnd();
Use console.groupCollapsed() instead of console.group() when you want the group to start in a collapsed state. This is useful for verbose logging that you want available without cluttering the visible console:
console.groupCollapsed('Request details (click to expand)');
console.log('Headers:', request.headers);
console.log('Body:', request.body);
console.log('Timestamp:', new Date().toISOString());
console.groupEnd();
String Substitution
Insert variables into console output using format specifiers:
const user = { name: 'Sarah', id: 42 };
console.log('User %s has ID %d', user.name, user.id);
// Output: User Sarah has ID 42
console.log('Memory usage: %o', performanceObject);
// %o renders as a clickable, expandable object
The available format specifiers are:
%s. string%dor%i. integer%f. floating point number%o. object (expandable)%O. object (formatted with JSON-style display)%c. CSS styling (apply the next argument as CSS)
Styling Console Output
Add CSS styling to make important messages stand out in a busy console:
console.log('%cImportant: ', 'color: red; font-weight: bold; font-size: 14px;', 'Action required');
console.log('%cSuccess: ', 'color: green; font-weight: bold;', 'Task completed');
console.log(
'%c[DEPLOY] %c Production deployment started',
'background: #e74c3c; color: white; padding: 2px 6px; border-radius: 3px;',
'color: #333; font-weight: bold;'
);
This technique is most useful in development frameworks and libraries that want their internal messages visually distinct from application code. You can also use it to make your own debug logs easier to spot in a long console output.
Console Utilities
$ and $$ Selectors
The console provides shorthand DOM selection functions that work like jQuery:
// Returns the first element matching the selector (like querySelector)
$('.submit-button')
// Returns all matching elements as an array (like querySelectorAll)
$$('div.item')
// Both support complex selectors
$$('form input[type="text"]:not([disabled])')
These are only available in the DevTools console itself, not in page scripts. They save keystrokes when you’re doing exploratory debugging and don’t want to type document.querySelector repeatedly.
$0 Through $4: Recently Inspected Elements
In the Elements panel, $0 refers to the most recently selected element. Chrome keeps a history of the last five elements you inspected:
$0 // Most recently selected element
$1 // Previously selected element
$2 // Selected two selections ago
// ...and so on through $4
This is useful for comparing properties across elements or testing DOM manipulation:
// Check if two inspected elements have the same parent
$0.parentElement === $1.parentElement // true or false
// Copy an attribute value from one element to another
$0.setAttribute('data-theme', $1.getAttribute('data-theme'));
copy(): Clipboard Access
Copy any JavaScript value directly to your clipboard:
copy(document.querySelector('html').outerHTML);
copy(JSON.stringify(window.__APP_STATE__, null, 2));
copy($$('a').map(a => a.href));
The copy() function serializes whatever you pass it. For objects, it converts to JSON automatically. This is especially useful for extracting API response data, configuration objects embedded in page state, or HTML snippets for further analysis.
monitor(): Function Calls
Automatically log every call to a function along with its arguments:
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}
monitor(calculateTotal);
calculateTotal([{price: 10}, {price: 20}]);
// Output: function calculateTotal called with arguments: Array(2) [{price: 10}, {price: 20}]
Use unmonitor(calculateTotal) to stop tracking. This is useful when you suspect a function is being called with unexpected arguments but don’t want to modify the source code to add logging.
Practical Debugging Workflows
Inspecting Network Response Data
Combine the console with the Network panel for a powerful debugging loop:
- Trigger an API request from your application
- In the Network panel, click the request and find the response
- Right-click the response body and choose “Copy response”
- In the console:
const data = JSON.parse(/* paste here */) - Now explore
datainteractively withconsole.table(data.results),console.dir(data), etc.
This workflow lets you analyze API responses with the full power of JavaScript without building throwaway test scripts.
Live Expression
Instead of repeatedly logging a value, use the Live Expression feature (the eye icon in the console toolbar) to pin an expression that continuously updates:
// Pin these as live expressions to watch values change in real time
window.scrollY
document.activeElement
performance.now()
Live expressions re-evaluate every 250ms and display the current value inline. This is particularly useful for debugging scroll handlers, focus management, or animation timing.
Conditional Breakpoints via Console
Set breakpoints programmatically when you identify problematic conditions:
function processItem(item) {
if (item.corrupted) {
debugger; // Only breaks on corrupted items
}
return transform(item);
}
You can also set conditional breakpoints in the Sources panel by right-clicking a line number and choosing “Add conditional breakpoint.” Type any JavaScript expression; execution only pauses when the expression evaluates to true.
Clearing the Console
Keep output clean during long debugging sessions:
console.clear(); // Clears all previous output
You can also press Ctrl+L (or Cmd+K on Mac) to clear without touching the keyboard shortcut. If you want to prevent console.clear() from working (for example, to preserve logs added by browser extensions), check “Preserve log” in the console settings.
Quick Reference: Console Command Summary
| Command | Purpose | When to Use |
|---|---|---|
console.log() |
General output | Daily use |
console.error() |
Error with stack trace | Error handling |
console.warn() |
Warning messages | Deprecation notices |
console.table() |
Tabular data display | Arrays and objects |
console.dir() |
Object property tree | DOM nodes, deep objects |
console.assert() |
Conditional logging | Runtime validation |
console.trace() |
Call stack snapshot | Tracking call origins |
console.time/End() |
Performance measurement | Benchmarking |
console.count() |
Execution counter | Event monitoring |
console.group() |
Collapsible log groups | Organized output |
debugger |
Hard breakpoint | Pausing execution |
$() / $$() |
DOM selection | Element inspection |
$0 |
Last selected element | Elements panel work |
copy() |
Clipboard export | Extracting data |
monitor() |
Function call logging | Call tracking |
Mastering these commands transforms the console from a print statement dumping ground into a proper interactive debugging environment. Start with console.table() and console.time() if you’re new to the advanced APIs, those two alone will visibly improve how quickly you can diagnose data shape problems and performance bottlenecks.
Try it: Paste your error into our Error Diagnostic for an instant fix.
Related Reading
- Svelte Devtools Chrome Extension Guide (2026)
- Chrome Devtools Workspaces Local Overrides — Developer Guide
- Chrome DevTools Responsive Design Mode Guide (2026)
- React Devtools Chrome Extension — Complete Developer Guide
- Chrome Devtools Snippets — Complete Developer Guide
- AWS Console Enhancer Chrome Extension Guide (2026)
- Chrome DevTools Tips for Frontend Developers. Additional techniques for maximizing your DevTools workflow
- JavaScript Debugging Techniques for Production. Strategies for debugging in live environments
Related guides: Mastering Browser Developer Tools
Built by theluckystrike. More at zovo.one
Find the right skill → Browse 155+ skills in our Skill Finder.