
Node.js 8 has a new utility function: util.promisify(). It converts a callback-based function to a Promise-based one. Since we are on this topic I would like to highlight one of the most straight forward explanation for promises that I have come across by Jecelyn Yeen
Imagine you are a kid. Your mom promises you that she'll get you a new phone next week. You don't know if you will get that phone until next week. Your mom can either really buy you a brand new phone, or stand you up and withhold the phone if she is not happy :(. Jecelyn Yeen
In a very abstract way, it does the following:
Takes a function following the common Node.js callback style, i.e. taking a
(err, value) => ...callback as the last argument, and returns a version that returns promises.
and
promisify(original)assumes that original is a function taking a callback as its final argument in all cases, and the returned function will result in undefined behaviour if it does not.
If you haven't got it already, it basically, a utility function that takes a regular function and converts it to a function that returns a promise.
It has the following syntax:
const wait = (delay, callback) => {
  /* β¦ */
};
promisify must be a callbackBut at the same time you can couple this with async to avoid the callback hell effectively.

const { promisify } = require('util');
const fs = require('fs');
const readFileAsync = promisify(fs.readFile); // (A)
//some path
const filePath = process.argv[2];
readFileAsync(filePath, { encoding: 'utf8' })
  .then((text) => {
    console.log('CONTENT:', text);
  })
  .catch((err) => {
    console.log('ERROR:', err);
  });
us implement the same using asnyc function:
const { promisify } = require('util');
const fs = require('fs');
const readFileAsync = promisify(fs.readFile);
const filePath = process.argv[2];
async function main() {
  try {
    const text = await readFileAsync(filePath, { encoding: 'utf8' });
    console.log('CONTENT:', text);
  } catch (err) {
    console.log('ERROR:', err);
  }
}
main();
There are a few changes and qwirks you should adher to before implementing promisify, they are:
callbacks of the following functions receive more than one result value (in addition to the error value):
child_process.exec;
child_process.execFile;
dns.lookup;
dns.lookupService;
fs.read;
fs.write;
If you promisify one of these functions, it returns an object of values (not a single value). For example, the callback of dns.lookup() has the following callback parameters:
const util = require('util');
const dns = require('dns');
const lookupAsync = util.promisify(dns.lookup);
lookupAsync('nodejs.org').then((obj) => console.log(obj));
// { address: '104.20.23.46', family: 4 }
There is a polyfill avaliable to take care of the older version of node servers you'll be running your application on. It can be installed via npm in the following manner:
npm install util.promisify
Now you can patch module utl on older versions of Node
const util = require('util');
require('util.promisify').shim();
const fs = require('fs');
const readFileAsync = util.promisify(fs.readFile);
I hope this post will make your life a tad easier. I recommend signing up to our newsletter to get the most of what's happening in the grizzly world.
Happy Grizzly π» Coding


Node.js 24 is here with game-changing features like V8 13.6, Float16Array, explicit resource management, WebAssembly Memory64, and npm 11. Learn what's new and how to upgrade smoothly.
This blog post focuses on the new experimental feature in React 18 called the use hook. It explains how the use hook can be used to create custom hooks that can be reused across different components, simplifying state management and making code more modular.
In this blog post we'll explore how Next.js can help you optimize your website for search engines From server-side rendering to automatic code splitting we will cover all the features that make Next.js a powerful tool for SEO optimization