util-inspect-isomorphic
v1.0.0
Published
An isomorphic port of the Node.js API require('node:util').inspect().
Readme
About
A dependency-free isomorphic port of the Node.js API require("node:util").inspect(). Works on any ES6 JS runtime, as it has no dependency on V8 or Node.js. Can be used in the browser, in React Native, etc.
Usage
Install as follows:
npm install util-inspect-isomorphicUse just like the original (see the official Node.js docs for full details):
import { inspect } from "util-inspect-isomorphic";
// Serialise Errors with cause:
console.error(inspect(new Error("Outer", { cause: new Error("Inner") })));
// Inspect deeply-nested objects:
console.log(inspect({ a: { b: { c: { d: {} } } } }), { depth: null });
// Print with colours:
console.log(inspect(["wow", new Date(), true], { colors: true }));
// Insert an underscore between every 3 digits:
console.log(inspect(1000000000, { numericSeparator: true }));Engine support
Requires ES6 and ESM support (or a bundler that can downlevel them).
Differences from the original
This library is a port of the Node.js core code in lib/internal/util/inspect.js (and any dependent files) as it was in main on June 2025, so approximately Node.js v24.1.0. Here are the main compromises that had to be made in the port:
Proxytypes cannot be inspected, soshowProxy: truehas no effect. Instead of theProxyitself, theProxytarget will be inspected.- For external (cross-realm, etc.) types, we cannot print the memory address, so just print
[External: <address unknown>]. - Limited
Promiseintrospection – we can't tell whether it is<pending>,<rejected>, or resolved, so we write<uninspectable>instead. - Type inspection can be fooled, as it doesn't use engine-level introspection.
- Not all types of TypedArray get special handling. Namely
Float16Array,BigInt64Array, andBigUint64Array. - Does not apply special colour-highlighting to stack trace lines that enter
node_modulesor Node.js core modules.
Sources
Here's a file-by-file summary of what was adapted from the Node.js internals or other projects:
- src/index.ts:
- src/inspect.ts:
- src/internal-assert.ts:
- src/internal-errors.ts:
- src/internal-util-types.ts:
- lib/internal/util/types.js
- Some code adapted from node-inspect-extracted, as per the code comments.
- src/internal-util.ts:
- src/internal-validators.ts:
- src/primordials.ts:
- node-primordials, itself a TypeScript port of lib/internal/per_context/primordials.js
- src/node-util.ts:
- src/node_util.cc
- Some code adapted from node-inspect-extracted, as per the code comments.
See also
I found out about the excellent node-inspect-extracted only after largely finishing this port. There are a few differences between our approaches.
node-inspect-extracted:- is a CommonJS library, written in JavaScript.
- is designed to be easy to keep up to date with upstream, whereas
util-inspect-isomorphicis a one-time snapshot. - has some tests.
util-inspect-isomorphic:- is a port to ESM, written in TypeScript.
- is confirmed to work in React Native.
- I found that I had to change calls such as
const { Object } = primordialstoprimordials.Objectto get it to run. I can't be sure whether it was a Hermes runtime issue or a Metro bundling issue.
- I found that I had to change calls such as
- is untested. Use at your own risk!
Contributing
# Clone the repo
git clone [email protected]:shirakaba/util-inspect-isomorphic.git
cd util-inspect-isomorphic
# Install the dev dependencies
npm install
# Build the code from TypeScript to JavaScript
npm run build
# Test the code (e.g. by making a new script)
node ./scripts/test.js