NodeJSThe util Module

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

util.promisify(fn)

Wrap a callback-style function so it returns a promise

util.callbackify(fn)

The reverse — wrap an async function as callback-style

util.inspect(obj, opts)

Produce the string console.log would print

util.format(fmt, ...args)

printf-style string formatting

util.parseArgs(opts)

Parse process.argv flags into structured options

util.types.*

Reliable type checks (isDate, isPromise, …)

util.deprecate(fn, msg)

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:

JS
import { promisify } from 'node:util'
import { readFile } from 'node:fs'

const readFileP = promisify(readFile)

const text = await readFileP('./data.txt', 'utf8')
console.log(text)
Often there is already a promise version
Before reaching for `promisify`, check for a built-in promise variant — `fs` has `node:fs/promises`, `dns` has `dns/promises`, etc. Use `promisify` for callback APIs that *lack* one (yours, or older libraries). It has a full page: [util.promisify](/nodejs/promisify).
promisify needs the error-first signature
`promisify` assumes the callback is the **last** argument and is called as `(err, value)`. Functions that don't follow this — multiple success values, or callback-not-last — won't convert correctly. For those, wrap them in a `new Promise(...)` by hand or use `fn[util.promisify.custom]` to define custom behavior.
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:

JS
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 tree
console.log truncates deep objects by default
`console.log` (which uses `inspect` internally) stops at **depth 2**, printing `[Object]` for anything deeper — a frequent "where did my data go?" surprise. Pass `{ depth: null }` to `util.inspect` to expand fully. You can also define a `[util.inspect.custom]` method on a class to control how its instances log.
parseArgs: structured CLI flags

Since Node 18.3, util.parseArgs parses command-line flags without a dependency — replacing hand-rolled process.argv slicing:

JS
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

JS
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

%s

String

%d / %i

Number / integer

%j

JSON

%o / %O

Object (via inspect)

%c

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):

JS
import { types } from 'node:util'

types.isPromise(Promise.resolve())   // true
types.isDate(new Date())             // true
types.isNativeError(new TypeError()) // true — even cross-realm
Next
Parse and build web addresses the correct, spec-compliant way: [The url Module](/nodejs/url-module).