Loupe Object Inspection Utility
Loupe is a robust, cross-platform utility for converting JavaScript objects into string representations, designed to work consistently in both Node.js and browser environments. It provides functionality similar to Node.js' built-in `util.inspect()`, making it a valuable tool for debugging and generating human-readable output of complex data structures. The current stable major version is `4.x`, with `v4.0.0` introducing significant breaking changes regarding custom inspection methods. The package maintains a moderate release cadence, with minor and patch updates preceding major version increments, reflecting ongoing development and refinement. As a core component within the Chai.js assertion library ecosystem, Loupe's key differentiator is its unified inspection behavior across diverse JavaScript runtimes, addressing the common challenge of inconsistent object serialization.
Common errors
-
TypeError: inspect is not a function
cause Attempting to call `require('loupe')` or `import loupe from 'loupe'` directly as a function, without destructuring the `inspect` named export.fixUse named import `import { inspect } from 'loupe';` for ESM or destructuring `const { inspect } = require('loupe');` for CommonJS. -
Custom inspection logic not being invoked for my object.
cause Using a plain `.inspect` property for custom inspection logic on an object, which was deprecated and removed in v4.0.0.fixFor `loupe` v4.0.0 and above, custom inspect methods must be defined using the `Symbol('nodejs.util.inspect.custom')` or `Symbol('chai/inspect')` symbol keys. Example: `obj[Symbol('nodejs.util.inspect.custom')] = function() { /* ... */ };`
Warnings
- breaking Version 4.0.0 removed support for custom inspection methods defined via a plain `.inspect` property on objects.
- gotcha When inspecting very large or deeply nested objects, the output can become excessively long and impact performance or readability.
- gotcha The `loupe` package outputs declaration maps ('.d.ts.map' files) prior to v4.0.0, which were then removed in v4.0.0.
Install
-
npm install loupe -
yarn add loupe -
pnpm add loupe
Imports
- inspect
import loupe from 'loupe'; // then `loupe.inspect` is correct, but direct destructuring is preferred
import { inspect } from 'loupe'; - inspect
const inspect = require('loupe'); // Then `inspect.inspect` would be needed, or a TypeError if called directlyconst { inspect } = require('loupe'); - Custom inspection
obj.inspect = function() { /* ... */ };obj[Symbol('nodejs.util.inspect.custom')] = function() { /* ... */ };
Quickstart
import { inspect } from 'loupe';
// Basic types
console.log(inspect({ foo: 'bar', baz: 123 }));
console.log(inspect([1, 'two', { three: 3 }]));
console.log(inspect(new Date('2023-01-15T10:00:00Z')));
console.log(inspect(/pattern/gi));
// Functions
function greet(name) { return `Hello, ${name}`; }
console.log(inspect(greet));
// Complex objects with custom inspection (v4.x compatible)
const customInspectable = {
value: 'secret',
[Symbol('nodejs.util.inspect.custom')]: function(depth, opts) {
return `CustomObject { value: '${this.value.slice(0, 3)}...' }`;
}
};
console.log(inspect(customInspectable));
// Errors and Promises
const error = new Error('Something went wrong');
console.log(inspect(error));
console.log(inspect(Promise.resolve(42)));