Wrap Any Callback API as a Promise
`util.promisify`
promisify converts Node-style (err, result) callback functions to promise-returning ones.
What you'll learn
- Use promisify on legacy APIs
- Recognize when standard /promises modules exist
util.promisify converts a Node-style callback function — one that
takes (err, result) as the last argument — into one that returns
a promise.
The Pattern
import { promisify } from "node:util";
import { exec } from "node:child_process";
const run = promisify(exec);
const { stdout, stderr } = await run("git status");
console.log(stdout); The original exec(cmd, callback) becomes run(cmd) returning a
promise.
When You Need It
Modern Node std-lib usually offers /promises versions already —
prefer those over promisify:
// instead of:
import { readFile } from "node:fs";
import { promisify } from "node:util";
const readFileAsync = promisify(readFile);
// use:
import { readFile } from "node:fs/promises"; You’ll reach for promisify when:
- A specific function has no built-in promise version (
exec,crypto.scrypt) - A third-party callback-based lib hasn’t published a promise API yet
A Crypto Example
import { scrypt } from "node:crypto";
import { promisify } from "node:util";
const scryptAsync = promisify(scrypt);
const key = await scryptAsync("password", "salt", 32);
console.log(key.toString("hex")); When NOT To
If you wrote the callback function yourself, just rewrite it to
return a promise directly. promisify is a bridge for legacy APIs.