The util Module
node:util is Node's toolbox of helpers — the standouts being promisify (turn a callback API into a promise-returning one), inspect (the engine behind console.log's object formatting), parseArgs (parse CLI flags), and format. These are small functions that remove real friction from everyday code.
The headline helpers
Function | Purpose |
|---|---|
| Wrap a callback-style function so it returns a promise |
| The reverse — wrap an async function as callback-style |
| Produce the string |
|
|
| Parse |
| Reliable type checks ( |
| Wrap a function to emit a deprecation warning |
promisify: escape callback APIs
Many older core functions follow the error-first callback convention. promisify converts any such function into one you can await:
import { promisify } from 'node:util'
import { readFile } from 'node:fs'
const readFileP = promisify(readFile)
const text = await readFileP('./data.txt', 'utf8')
console.log(text)inspect: see objects as console.log does
util.inspect turns any value into the readable string console.log would show — but you control depth, colors, and whether hidden properties appear. Invaluable for logging deeply-nested objects:
import { inspect } from 'node:util'
const data = { a: { b: { c: { d: 1 } } }, list: [1, 2, 3] }
console.log(inspect(data, { depth: null, colors: true }))
// ↑ no depth limit — show the whole treeparseArgs: structured CLI flags
Since Node 18.3, util.parseArgs parses command-line flags without a dependency — replacing hand-rolled process.argv slicing:
import { parseArgs } from 'node:util'
const { values, positionals } = parseArgs({
options: {
name: { type: 'string', short: 'n' },
verbose: { type: 'boolean', short: 'v' },
},
allowPositionals: true,
})
// $ node app.js build --name=api -v
console.log(values) // { name: 'api', verbose: true }
console.log(positionals) // ['build']The lower-level process.argv it builds on is covered in process.argv.
format: printf-style strings
import { format } from 'node:util'
format('%s is %d years old', 'Ada', 36) // 'Ada is 36 years old'
format('%o', { x: 1 }) // '{ x: 1 }' (object)
format('%j', { x: 1 }) // '{"x":1}' (JSON)Specifier | Formats as |
|---|---|
| String |
| Number / integer |
| JSON |
| Object (via inspect) |
| CSS (ignored in Node, consumed in browsers) |
Reliable type checks
util.types answers questions typeof and instanceof get wrong — especially across realms (e.g. objects from a different VM context):
import { types } from 'node:util'
types.isPromise(Promise.resolve()) // true
types.isDate(new Date()) // true
types.isNativeError(new TypeError()) // true — even cross-realm