Inspect deeply nested objects in Node.js

Expand nested values with util.inspect or console.dir, and understand the output limits and data transformations involved in JSON serialization.

Best practices
Illustration of monitoring and request timing

Use console.dir(value, { depth: null }) or util.inspect(value, { depth: null }) to remove the usual inspection-depth limit. This helps when Node's terminal output collapses nested values to [Object].

Configure util.inspect

const { inspect } = require('node:util');
const value = { service: { request: { result: { status: 'ok' } } } };
console.log(inspect(value, { depth: null }));

The default inspection depth is 2. Setting it to null removes that depth limit, but other limits still apply: long arrays or strings may be truncated, and the inspection output has an overall size limit. For a bounded object, maxArrayLength: null and maxStringLength: null can remove those individual limits.

Inspection is a debugging representation, not a stable serialization format. It handles circular references, but custom inspection hooks and options can change what appears.

Use console.dir directly

console.dir(value, {
  depth: null,
  colors: Boolean(process.stdout.isTTY),
});

This accepts inspection options without a separate formatting call. Unlike ordinary custom inspection, console.dir() bypasses a custom inspection function on the object. That difference can matter when comparing it with console.log() or util.inspect().

Serialize JSON-compatible data

console.log(JSON.stringify(value, null, 2));

The third argument adds indentation. JSON changes or omits values that do not have an equivalent JSON representation: object properties containing functions or undefined are omitted, while such array elements become null. Circular references normally throw; BigInt values also normally throw unless you provide suitable handling. Objects can customize serialization through toJSON().

Choose JSON when its data model is the desired output. Choose inspection when you need to understand JavaScript values while debugging.

FAQ

Does depth: null print absolutely everything? No. It removes the depth cutoff, not all truncation or visibility rules. Non-enumerable properties, custom hooks, maximum lengths, and output limits are separate concerns.

Is this suitable for production logging? Unbounded inspection can expose credentials and consume substantial CPU. Use bounded, redacted fields in structured logs when software will parse the records. A logging library such as Pino or Winston can help enforce that policy; the library alone does not make arbitrary objects safe to log.

Can printing a large object slow the process? Yes. Inspection and JSON serialization do synchronous work on the calling thread. Output writes have destination-specific behavior too. Limit the data, especially on high-traffic paths.

Do browser consoles behave the same way? No. Browser developer tools offer their own interactive representations and may show objects differently over time. Do not infer Node's text-output behavior from a browser console.

If you collect application logs with Guance, verify field parsing and redaction with a controlled sample before depending on those fields during an incident.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting