pify vs async vs bluebird vs q vs util.promisify
JavaScript Promise Libraries Comparison
1 Year
pifyasyncbluebirdqutil.promisifySimilar Packages:
What's JavaScript Promise Libraries?

These libraries provide various utilities for handling asynchronous operations in JavaScript, particularly through the use of Promises. They help streamline the process of working with asynchronous code, making it easier to manage complex workflows, avoid callback hell, and improve code readability. Each library has its unique features and design philosophies, catering to different needs and preferences in asynchronous programming.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
pify75,639,8551,50413.6 kB0-MIT
async56,124,85928,234808 kB139 months agoMIT
bluebird26,928,12720,469-1225 years agoMIT
q10,509,12914,950-115-MIT
util.promisify8,529,49012726.1 kB25 months agoMIT
Feature Comparison: pify vs async vs bluebird vs q vs util.promisify

Performance

  • pify:

    Pify's performance is generally good as it simply wraps existing functions, but it does not offer the advanced performance optimizations found in dedicated Promise libraries like Bluebird.

  • async:

    Async is designed for flexibility and ease of use, but its performance may not match that of Promise-centric libraries when dealing with large-scale asynchronous operations due to its callback-based nature.

  • bluebird:

    Bluebird is highly optimized for performance, making it one of the fastest Promise libraries available. It includes features like optimized Promise chaining and efficient memory usage, which are crucial for performance-sensitive applications.

  • q:

    Q provides a lightweight solution for Promises but may not be as performant as Bluebird in scenarios involving heavy Promise chaining or large-scale asynchronous operations.

  • util.promisify:

    Util.promisify is efficient for converting callback functions to Promises, but its performance is tied to the underlying function being promisified. It is not a standalone library, so performance depends on the context.

Feature Set

  • pify:

    Pify is minimalistic, focusing solely on converting callback functions to Promises. It does not provide additional features beyond this utility, making it less versatile than others.

  • async:

    Async offers a rich set of control flow functions, including series, parallel, and waterfall execution patterns, making it versatile for various asynchronous workflows.

  • bluebird:

    Bluebird provides a comprehensive feature set, including advanced Promise methods like map, reduce, and filter, as well as cancellation and progress tracking, making it suitable for complex asynchronous tasks.

  • q:

    Q includes basic Promise functionalities and some additional utilities like deferred objects, but it lacks the extensive feature set found in more modern libraries like Bluebird.

  • util.promisify:

    Util.promisify is straightforward and effective for converting callbacks to Promises, but it does not offer additional features or utilities for managing Promises.

Ease of Use

  • pify:

    Pify is extremely easy to use, requiring minimal setup to convert functions to Promises, making it ideal for quick integrations.

  • async:

    Async's API is intuitive for those familiar with callback patterns, but it may require a learning curve for developers transitioning to Promises.

  • bluebird:

    Bluebird's API is user-friendly and well-documented, making it easy to adopt for developers familiar with Promises. Its extensive features can be overwhelming for beginners.

  • q:

    Q has a simple API that is easy to understand, especially for developers new to Promises, but it may feel limited compared to more feature-rich libraries.

  • util.promisify:

    Util.promisify is straightforward to use, especially for Node.js developers, as it integrates seamlessly with existing callback-based functions.

Compatibility

  • pify:

    Pify is primarily designed for Node.js but can be used in browser environments with proper polyfills for Node-style callbacks.

  • async:

    Async is compatible with both Node.js and browser environments, making it a versatile choice for various JavaScript applications.

  • bluebird:

    Bluebird works well in both Node.js and browser contexts, providing a consistent experience across platforms.

  • q:

    Q is compatible with both Node.js and browsers, allowing for flexibility in application development across different environments.

  • util.promisify:

    Util.promisify is a Node.js built-in function, so it is only available in Node.js environments and not in browsers.

Community and Support

  • pify:

    Pify is less commonly used compared to others, which may result in fewer community resources, but it is simple enough that extensive support is often unnecessary.

  • async:

    Async has a strong community and is widely used in the Node.js ecosystem, ensuring good support and a wealth of resources.

  • bluebird:

    Bluebird has a large user base and extensive documentation, providing excellent community support and resources for developers.

  • q:

    Q has a decent community, but it has seen less active development compared to more modern libraries, which may affect long-term support.

  • util.promisify:

    Util.promisify benefits from the support of the Node.js community, but being a built-in function, it does not have a separate community or extensive resources.

How to Choose: pify vs async vs bluebird vs q vs util.promisify
  • pify:

    Select Pify if you need a simple utility to convert Node.js-style callback functions into Promises. It's particularly useful for integrating existing callback-based libraries into a Promise-based workflow without extensive modifications.

  • async:

    Choose Async if you need a comprehensive toolkit for managing asynchronous control flow with a focus on callbacks, especially in Node.js environments. It offers a variety of functions for parallel and series execution, making it suitable for complex workflows.

  • bluebird:

    Opt for Bluebird if you require a high-performance Promise library that offers extensive features like cancellation, progress tracking, and utility functions for working with Promises. It's ideal for applications that need robust Promise capabilities and performance optimization.

  • q:

    Use Q if you want a lightweight Promise library that provides a straightforward API for working with Promises. It is suitable for projects that require basic Promise functionality without the overhead of additional features.

  • util.promisify:

    Choose util.promisify if you prefer a built-in solution for converting callback-based functions into Promises in Node.js. It is a simple and effective way to leverage Promises without adding external dependencies.

README for pify

pify

Promisify a callback-style function

Install

npm install pify

Usage

import fs from 'fs';
import pify from 'pify';

// Promisify a single function.
const data = await pify(fs.readFile)('package.json', 'utf8');
console.log(JSON.parse(data).name);
//=> 'pify'

// Promisify all methods in a module.
const data2 = await pify(fs).readFile('package.json', 'utf8');
console.log(JSON.parse(data2).name);
//=> 'pify'

API

pify(input, options?)

Returns a Promise wrapped version of the supplied function or module.

input

Type: Function | object

Callback-style function or module whose methods you want to promisify.

options

Type: object

multiArgs

Type: boolean
Default: false

By default, the promisified function will only return the second argument from the callback, which works fine for most APIs. This option can be useful for modules like request that return multiple arguments. Turning this on will make it return an array of all arguments from the callback, excluding the error argument, instead of just the second argument. This also applies to rejections, where it returns an array of all the callback arguments, including the error.

import request from 'request';
import pify from 'pify';

const pRequest = pify(request, {multiArgs: true});

const [httpResponse, body] = await pRequest('https://sindresorhus.com');
include

Type: Array<string | RegExp>

Methods in a module to promisify. Remaining methods will be left untouched.

exclude

Type: Array<string | RegExp>
Default: [/.+(?:Sync|Stream)$/]

Methods in a module not to promisify. Methods with names ending with 'Sync' are excluded by default.

excludeMain

Type: boolean
Default: false

If the given module is a function itself, it will be promisified. Enable this option if you want to promisify only methods of the module.

import pify from 'pify';

function fn() {
	return true;
}

fn.method = (data, callback) => {
	setImmediate(() => {
		callback(null, data);
	});
};

// Promisify methods but not `fn()`.
const promiseFn = pify(fn, {excludeMain: true});

if (promiseFn()) {
	console.log(await promiseFn.method('hi'));
}
errorFirst

Type: boolean
Default: true

Whether the callback has an error as the first argument. You'll want to set this to false if you're dealing with an API that doesn't have an error as the first argument, like fs.exists(), some browser APIs, Chrome Extension APIs, etc.

promiseModule

Type: Function

Custom promise module to use instead of the native one.

FAQ

How is this different from Node.js's util.promisify?

  • Pify existed long before util.promisify.
  • Pify is faster.
  • Pify supports wrapping a whole module/object, not just a specific method.
  • Pify has useful options like the ability to handle multiple arguments (multiArgs).
  • Pify does not have magic behavior for certain Node.js methods and instead focuses on predictability.

How can I promisify a single class method?

Class methods are not bound, so when they're not called on the class itself, they don't have any context. You can either promisify the whole class or use .bind().

import pify from 'pify';
import SomeClass from './some-class.js';

const someInstance = new SomeClass();

// ❌ `someFunction` can't access its class context.
const someFunction = pify(someClass.someFunction);

// ✅ The whole class is promisified and the `someFunction` method is called on its class.
const someClassPromisified = pify(someClass);
someClassPromisified.someFunction();

// ✅ `someFunction` is bound to its class before being promisified.
const someFunction = pify(someClass.someFunction.bind(someClass));

Why is pify choosing the last function overload when using it with TypeScript?

If you're using TypeScript and your input has function overloads, then only the last overload will be chosen and promisified.

If you need to choose a different overload, consider using a type assertion:

function overloadedFunction(input: number, callback: (error: unknown, data: number => void): void
function overloadedFunction(input: string, callback: (error: unknown, data: string) => void): void {
	/* … */
}

const fn = pify(overloadedFunction as (input: number, callback: (error: unknown, data: number) => void) => void)
// ^ ? (input: number) => Promise<number>

Related

  • p-event - Promisify an event by waiting for it to be emitted
  • p-map - Map over promises concurrently
  • More…

Get professional support for 'pify' with a Tidelift subscription
Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies.