The browser console in Firefox's DevTools is more powerful than most developers realize. Beyond console.log(), there's a full JavaScript REPL, built-in helper functions, persistent logging, and utilities for DOM inspection and async debugging. This guide covers the features worth knowing.
Console Basics Recap
F12 → Console tab, or Ctrl+Shift+K to open directly.
The console shows:
- JavaScript errors and warnings
- Network errors
- Security policy violations (CSP)
- Your
console.*calls from scripts
The multi-line input at the bottom is a full JavaScript REPL — you can write multi-line scripts, not just one-liners.
Console Methods Beyond console.log
console.log('Standard log');
console.info('ℹ️ Informational');
console.warn('⚠️ Warning');
console.error('❌ Error');
console.debug('Debug (filtered by default)');
Grouping:
console.group('User data');
console.log('Name:', user.name);
console.log('Email:', user.email);
console.groupEnd();
console.groupCollapsed('Verbose data'); // starts collapsed
console.log('lots', 'of', 'data');
console.groupEnd();
Tables:
console.table([
{ name: 'Alice', age: 30 },
{ name: 'Bob', age: 25 }
]);
// Renders as a sortable table in DevTools
Timing:
console.time('fetchUsers');
const users = await fetchUsers();
console.timeEnd('fetchUsers');
// Logs: fetchUsers: 347ms
console.timeLog('fetchUsers', 'after processing'); // intermediate timing
Counting:
function processItem(type) {
console.count(type); // counts calls per label
// ...
}
processItem('A'); // A: 1
processItem('B'); // B: 1
processItem('A'); // A: 2
console.countReset('A');
Assertions:
console.assert(value !== null, 'Value should not be null', { value });
// Only logs if the condition is false — silent on success
Traces:
console.trace('Who called this?');
// Logs a stack trace from the current point
Firefox-Specific Console Helpers
Firefox's DevTools console has built-in helper functions not available in production code:
$0: the currently selected element in the Inspector
$1, $2: previous selections
$(selector): document.querySelector() shorthand
$$(selector): document.querySelectorAll() returning an array
$x(xpath): select elements by XPath
inspect(obj): opens the object in the DOM inspector
// Select an element and inspect it
inspect($$('button')[0])
// Find all elements with data-* attributes
$$('[data-testid]').map(el => el.getAttribute('data-testid'))
copy(value): copies any value to clipboard (useful for copying large objects)
copy(JSON.stringify(someObject, null, 2))
// Now paste the formatted JSON anywhere
Persistent Logging
Normally, the console clears when you navigate. Enable "Persist Logs" (checkbox in the console toolbar) to keep logs across page navigations.
Useful for:
- Debugging redirect flows (console.log before redirect, see it after the redirect)
- Tracking which page a specific error came from
- OAuth/SSO flows where you're redirected multiple times
Console Filter and Search
The filter bar at the top of the console filters displayed messages. Prefix options:
- No prefix: filter message text
-
-: exclude pattern -
/regex/: use regex
The dropdown to the right of the filter lets you show/hide specific log levels (Errors, Warnings, Logs, Info, Debug).
Custom categories: console.log('%ccategory', 'color: blue; font-weight: bold', 'message') — you can use CSS styling to visually distinguish your log categories.
Multi-Line REPL
Press Shift+Enter to add a new line without executing. The console becomes a multi-line editor for more complex scripts:
async function checkAllEndpoints() {
const endpoints = ['/api/health', '/api/version', '/api/status'];
for (const ep of endpoints) {
const res = await fetch(ep);
console.log(ep, res.status);
}
}
checkAllEndpoints();
The multi-line editor also supports:
- Tab completion
- Up/down arrow for history
-
Ctrl+Rfor reverse history search (Firefox 114+)
Async/Await in the Console
Firefox's console supports top-level await:
// Works directly in console:
const data = await fetch('/api/users').then(r => r.json());
console.table(data);
No need to wrap in an async function. The console handles the await at the top level.
Error Stack Traces
Firefox shows clickable stack traces in errors. Click any file/line link to jump to the Debugger at that exact location.
For minified code with source maps, Firefox deminifies the stack trace automatically if the .map file is available (from source maps header or embedded source map comment).
console.log() Performance in Production
console.log() is not zero-cost in production:
- String formatting is expensive if you pass objects with lots of properties
- Even if the output is filtered, the arguments are still evaluated
In production builds, strip console calls or use a logging library that can be disabled. Babel plugin transform-remove-console removes all console.* calls from production builds.
Firefox's about:performance shows CPU usage per tab — a useful way to measure whether your logging is significantly impacting performance.
Browser Console vs. DevTools Console
Ctrl+Shift+J (or about:blank → F12 → Console) opens the Browser Console — it shows errors from ALL tabs, not just the current one, plus browser chrome errors and extension errors.
The Browser Console is useful for:
- Debugging Firefox extensions (your extension's errors show here)
- Finding errors from multiple tabs simultaneously
- Seeing browser-level JavaScript errors (chrome errors)
The regular DevTools console (F12) is per-tab. The Browser Console is global.
Evaluating in Specific Frames
If a page has iframes, the console by default evaluates in the top-level frame. The frame selector dropdown (at the top of the console) lets you switch to evaluating in a specific frame:
[top] example.com
[frame] iframe.example.com
[frame] ads.example.com
Select iframe.example.com → now document refers to that frame's document, and you can inspect/modify it directly.
Top comments (0)