Browser Console Debugging Tricks
A practical cheatsheet of browser DevTools console tricks for faster debugging including table, group, styling, timing, and selection helpers.
Code
Browser Console Debugging Tricks
A practical cheatsheet for the DevTools console. Most of these work in Chrome and Edge; the
Console Utilities API helpers ($0, $_, copy, monitor, debug, inspect) are only
available when you type them in the console, not in committed source. Firefox supports a subset.
Tabular and structured output
// Render an array of objects as a sortable table
console.table(users);
// Limit to specific columns
console.table(users, ["id", "name"]);
// An object becomes a table keyed by its properties
console.table({ a: 1, b: 2 });
// Inspect a DOM element as a JS object (properties) instead of as HTML
console.dir(document.body);
// console.log(el) shows the HTML tree; console.dir(el) shows the object
Grouping logs
console.group("Request"); // start an expanded group
console.log("url:", url);
console.log("status:", status);
console.groupEnd(); // close it
console.groupCollapsed("Details"); // same, but starts collapsed
console.log("headers", headers);
console.groupEnd();
Groups nest, so call groupEnd() once per group/groupCollapsed.
Styling with %c
// %c applies the next argument as CSS to the text that follows it
console.log("%cLoaded", "color:#0f0;font-weight:bold;");
// Multiple %c segments, one CSS string each
console.log(
"%cOK %cdone",
"color:white;background:green;padding:2px 4px;border-radius:3px",
"color:gray"
);
Supported CSS is limited (color, background, font, padding, border, etc.) — no layout.
Timing
console.time("fetch"); // start a named timer
await fetch("/api");
console.timeLog("fetch"); // log elapsed without stopping
console.timeEnd("fetch"); // log elapsed and stop the timer
console.count("render"); // how many times this line ran
console.countReset("render"); // reset that counter
// Mark spans in the Performance panel timeline
console.timeStamp("data ready");
Selection helpers ($0, $_)
$0 // the DOM element currently selected in the Elements panel
$1 // the previously selected element ($2 ... $4 go further back)
$_ // the value of the last evaluated expression
2 + 2; // -> 4
$_ * 10; // -> 40
$0.style.outline = "2px solid red"; // highlight the inspected node
// Query shortcuts (console only)
$("button.primary"); // like document.querySelector
$$("li"); // like document.querySelectorAll, returns a real Array
$x("//a[@href]"); // evaluate an XPath, returns an array of nodes
copy() and inspect()
copy(JSON.stringify(state, null, 2)); // put a value on the system clipboard
copy($0); // copy the inspected element's markup
inspect(document.querySelector("#app")); // reveal a node/function in Elements/Sources
Breaking on function calls
monitor(myFunc); // log every call to myFunc with its arguments
unmonitor(myFunc); // stop logging
debug(myFunc); // set a breakpoint that fires whenever myFunc is called
undebug(myFunc); // remove that breakpoint
monitorEvents(window, "resize"); // log events on a target
unmonitorEvents(window, "resize");
getEventListeners($0); // list listeners attached to an element
Live expressions
In Chrome/Edge, click the eye icon at the top of the Console to pin a live expression — an expression that re-evaluates continuously and shows its current value above the log stream.
// Useful live expressions to pin:
document.activeElement // what currently has focus
performance.memory?.usedJSHeapSize
window.scrollY
document.querySelectorAll(".row").length
Live expressions never write to the log, so they're great for values that change every frame.
Common workflows
1. Inspect an API response as a table
const res = await fetch("/api/users").then(r => r.json());
console.table(res, ["id", "name", "email"]);
copy(res); // grab the full payload for a bug report
2. Time and count a hot render path
function render(item) {
console.count("render");
console.time("render-" + item.id);
// ...work...
console.timeEnd("render-" + item.id);
}
// later, see the total:
console.countReset("render");
3. Trace why a function fires
debug(updateCart); // pause in Sources every time it's called
// reproduce the bug in the page, inspect the call stack, then:
undebug(updateCart);
4. Grab and tweak the element you're looking at
// Select a node in the Elements panel, then in the Console:
$0.classList.add("debug-highlight");
copy($0.outerHTML); // paste the markup elsewhere
getEventListeners($0); // see what's bound to it
Gotchas / tips
$0,$_,$,$$,copy,monitor,debug,inspect, andgetEventListenersare part of the Console Utilities API — they exist only in the console and will throwReferenceErrorif left in shipped code.$and$$are only aliases when the page does not define its own$(e.g. jQuery); if a library owns$, the console aliases are shadowed.console.tabletruncates very large arrays and only tabulates own enumerable properties.console.dir(el)vsconsole.log(el): usedirto see the JS object/properties,logfor the interactive HTML tree.- Timer names must match exactly between
time/timeLog/timeEnd; a mismatch logs a warning and is silently ignored. performance.memoryis Chrome-only and may beundefined, so guard with?..- Strip
console.*calls from production with a bundler plugin ordrop_console— leftover logs leak data and slow hot loops.
Browser Console Debugging Tricks
A compact reference for the browser DevTools console features that turn console.log debugging
into something actually fast: tabular output, grouped logs, styled messages, timers, element
selection helpers, and breakpoint utilities.
What this is
A copy-pasteable cheatsheet covering console.table, console.group, console.dir, %c
styling, console.time, the $0/$_ selection helpers, copy(), monitor(), debug(), and
live expressions. These are utilities built into Chrome, Edge, and (mostly) Firefox DevTools.
When to use it
Reach for these when console.log alone is too noisy: inspecting arrays of objects, tracing
nested call flow, timing hot paths, or grabbing the currently inspected DOM node without
retyping a selector. Many of the helpers (copy, monitor, $0) only exist in the Console
itself, not in your shipped code.
Full cheatsheet
The complete, copy-pasteable reference lives in the snippet: snippets/markdown.md.