object-inspect

Zero-dependency string representations of any JavaScript value, including circular references and DOM elements.

Library
npm
v1.13.4
160stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
44/100Fair
Development Activity8
Maintenance20
Community68
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
65/100Good
Architecture65
Code Quality78
Innovation72
Learning Curve45

object-inspect is the utility maintained by the inspect-js collective that turns any JavaScript value — objects, arrays, Maps, Sets, WeakRefs, DOM elements, BigInts, symbols, and circular structures — into a readable string representation, mirroring Node’s built-in util.inspect but working identically in the browser. It ships as a single dependency-free module and is one of the most widely relied-upon low-level packages in the npm ecosystem, pulled in transitively by tools like tape and countless test frameworks and CLI utilities that need to print values for debugging or assertion output.

Beyond the basics, it handles the edge cases that naive JSON.stringify or string coercion get wrong: circular references are detected and printed as [Circular], custom inspect methods and util.inspect.custom symbols are honored, numbers can be rendered with numeric separators, and options like quoteStyle, indent, and maxStringLength give callers fine control over the output format without needing Node’s util module.

What You Get

  • Single exported function - require('object-inspect') returns one function, inspect(obj, opts), with no class or namespace to learn.
  • Circular reference detection - Self-referential objects and arrays are tracked via a seen list and printed as [Circular] instead of recursing forever.
  • Custom inspect method support - Objects with a util.inspect.custom symbol or an .inspect() method have that output honored, matching Node’s own conventions.
  • Fine-grained formatting options - quoteStyle, indent, maxStringLength, numericSeparator, customInspect, and depth let callers shape the exact output string.
  • Zero runtime dependencies - The entire implementation lives in one file (index.js) with no external packages required at install time.

Common Use Cases

  • Test assertion output - Test frameworks like tape print expected vs. actual values using object-inspect so failures are readable.
  • CLI debugging tools - Command-line tools log complex nested data structures to the terminal in a consistent, quoted format.
  • Browser polyfills for console.log - Browser-targeted logging shims use it to approximate Node’s console formatting where util.inspect isn’t available.
  • Error message formatting - Libraries embed inspected values directly into thrown error messages so consumers see the offending value, not [object Object].

Under The Hood

Architecture index.js exports a single recursive function that dispatches on the runtime type of the value being inspected: a long, explicit conditional chain checks for undefined, null, primitives, functions, symbols, DOM elements, arrays, Errors, custom-inspect-bearing objects, Map/Set/WeakMap/WeakSet/WeakRef, boxed primitives, and finally plain objects, with an internal inspect() closure that threads a seen array through every recursive call to detect circular references before they cause infinite recursion. Module-scope variables cache built-in prototype methods (Array.prototype.slice, String.prototype.replace, Object.prototype.toString, and so on) at load time, guarding the implementation against later monkey-patching of those globals. The whole library is intentionally a single flat file with no internal module boundaries — appropriate for a leaf-level utility that has no dependents to layer against.

Tech Stack The package is plain, dependency-free ES5-compatible JavaScript with no TypeScript and no build step; it is published to npm as raw source. Its browser field in package.json swaps out util.inspect.js (a one-line re-export of Node’s util.inspect) so bundlers targeting the browser don’t try to pull in Node’s util module. devDependencies are limited to test-time feature-detection shims (has-tostringtag, has-symbols, for-each, mock-property), the tape test runner, nyc for coverage, eslint with the @ljharb/eslint-config preset, and auto-changelog for release notes. CI runs via GitHub Actions across multiple Node version ranges (separate aught/tens/twenties workflows) plus a rebase-check workflow.

Code Quality The test/ directory contains around twenty focused test files exercising circular references, BigInts, DOM elements, array holes, indentation options, quote styles, Symbol.toStringTag precedence, and undefined/null handling, run through tape with nyc coverage instrumentation. Invalid option values (bad quoteStyle, maxStringLength, indent, customInspect, numericSeparator) throw explicit TypeErrors rather than failing silently. Internal variable naming favors terse, cached references to built-in methods ($slice, $replace, $test) — a deliberate zero-dependency-ecosystem convention that trades surface readability for defense against prototype tampering. There are no static types; correctness is enforced through the test suite and a strict ESLint configuration, plus a separate test:corejs script that re-runs the suite against core-js polyfills for older-engine compatibility, and a post-test npm audit step.

API Design The public surface is a single function, inspect(obj, opts), with well-documented, independently validated options and sensible defaults (single quotes, unlimited string length, custom-inspect honored by default) — there is effectively no learning curve to call it correctly for the common case, while power users get fine-grained control (quote style, indentation, depth, numeric separators) without touching Node’s util module. The zero-dependency, monkey-patch-resistant implementation is a genuine craftsmanship choice that most comparable formatting libraries skip, at the cost of a denser, less approachable source file for contributors.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search