console.log() is the debugging tool every developer starts with, and it is still useful. Used well, it answers the question “what is this value right now?”
Log more than one thing, with labels
const user = { name: "Maya", age: 28 };
const items = [1, 2, 3];
console.log("user:", user);
console.log("items:", items, "count:", items.length);
console.log({ user, items }); // logs an object with named properties: very handy
The last form, console.log({ variable }), prints the name next to the value, so you do not need to type labels.
Different levels
console.log("Normal information");
console.info("Informational message");
console.warn("A warning: something looks wrong");
console.error("An error: something failed");
The browser console colours them and lets you filter by level, so errors do not get lost in noise.
console.table: lists of objects
const people = [
{ name: "Maya", role: "Developer" },
{ name: "Arjun", role: "Designer" },
{ name: "Sam", role: "Writer" }
];
console.table(people);
In a browser console, this displays a real, sortable table. It is the best way to inspect arrays of objects.
Grouping
console.group("Order #1042");
console.log("Customer: Maya");
console.log("Total: $59");
console.groupEnd();
In the browser, groups can be collapsed. They keep related messages together.
Counting and timing
for (let i = 0; i < 3; i++) {
console.count("loop pass"); // loop pass: 1, 2, 3
}
console.time("work");
for (let i = 0; i < 100000; i++) { Math.sqrt(i); }
console.timeEnd("work"); // prints something like: work: 0.8 ms
console.assert
Logs an error only if the condition is false: a quiet check.
const total = 5;
console.assert(total === 5, "total should be 5"); // nothing printed
console.assert(total === 6, "total should be 6, got", total); // error on purpose: assertion fails
console.dir and console.trace
console.dir(element) shows an object’s properties (instead of its HTML for DOM elements). console.trace() prints where the current function was called from.
function inner() { console.trace("who called me?"); }
function outer() { inner(); }
outer();
Log objects carefully
The browser console shows live objects, and displays their current state when you expand them, not the state at log time. If an object changes right after, copy it to see a snapshot:
const data = { count: 1 };
console.log(JSON.stringify(data)); // → {"count":1} (a snapshot)
data.count = 2;
console.log(data); // → { count: 2 }
Styling and clearing
console.log("%cHello", "color: tomato; font-weight: bold") styles a message. console.clear() clears the console.
Clean up
Remove debugging logs before shipping, or use a tool that strips them. Logs can leak information and slow down busy code. In real projects, use a logging helper you can turn off.
When console.log is not enough
If a bug needs you to watch values change over time, or step through code line by line, use the debugger: Breakpoints and the debugger Statement.
Quick habit
console.log("in the else branch")). Often that is enough to see the problem.