Bluebird NPM: Bluebird JS Promise with Example
โก Smart Summary
Bluebird JS is a fully featured Promise library for JavaScript whose defining capability is promisification: converting callback-based Node modules into promise-returning ones, so an entire library such as the MongoDB driver can be used asynchronously.

What is Bluebird JS?
Bluebird JS is a fully featured Promise library for JavaScript. Its strongest feature is that it allows you to โpromisifyโ other Node modules in order to use them asynchronously. Promisify is a concept applied to callback functions, and it ensures that every callback function which is called returns a value.
So if a Node.js module contains a callback function which does not return a value, promisifying that module automatically modifies all the functions in it so that each one returns a value.
This means you can use Bluebird to make the MongoDB module run asynchronously, which adds another level of ease when writing Node.js applications.
The example below first establishes a connection to the โEmployeeโ collection in the โEmployeeDBโ database. Once the connection is established, it retrieves all of the records in the collection and displays them in the console.
How to Generate Promises with Bluebird JS Library
Here is a step by step example showing how to generate promises with the Bluebird JS library.
Step 1) Installing the NPM modules
To use Bluebird from within a Node application, the Bluebird module is required. Install it with the command below:
npm install bluebird
Step 2) Include the Bluebird module
The next step is to include the Bluebird module in your code and promisify the entire MongoDB module. Promisifying here means Bluebird ensures that every method defined in the MongoDB library returns a promise.
Code Explanation:
- The
requirecommand includes the Bluebird library. - Bluebird’s
.promisifyAll()method creates an async version of every method the MongoDB module provides, so each one runs in the background and returns a promise.
Step 3) Connect to the database
The final step is to connect to the database, retrieve all the records in the collection, and display them in the console log.
Code Explanation:
- Notice the
connectAsyncmethod is used instead of the normalconnectmethod. Bluebird appends the Async suffix to each method in the MongoDB library to distinguish the calls that return promises from those that do not. Methods without the Async suffix carry no such guarantee. - Similar to
connectAsync, thefindAsyncmethod returns all of the records in the MongoDB โEmployeeโ collection. - If
findAsyncresolves successfully, the following block iterates through each record in the collection and displays it in the console log.
If the steps above are carried out properly, all of the documents in the Employee collection are displayed in the console, as shown in the output below.
Here is the complete code for reference:
var Promise = require('bluebird'); // promisifyAll adds an Async variant of every MongoDB method var mongoClient = Promise.promisifyAll(require('mongodb')).MongoClient; mongoClient.connectAsync('mongodb://localhost/EmployeeDB') .then(function(db) { return db.collection('Employee').findAsync({}); }) .then(function(cursor) { cursor.each(function(err, doc) { console.log(doc); }); });
โ ๏ธ Driver version note: the code above targets MongoDB Node driver 2.x, where connect resolves with a database object. From driver 3.0 onward it resolves with a MongoClient, so the chain must call client.db('EmployeeDB').collection('Employee') instead of db.collection('Employee'). Modern driver versions also return native promises already, which makes promisifyAll unnecessary for MongoDB specifically.
Bluebird vs Native Promises: Which to Use
When Bluebird was first written, Node had no promise support at all, so the library filled a genuine gap in the platform. Node has shipped native promises since version 4 and async/await since version 7.6, which changes the calculation considerably for anyone starting a project today.
| Aspect | Bluebird | Native Promises |
|---|---|---|
| Dependency | An npm package to install and maintain | Built into the runtime |
| Promisifying callbacks | promisifyAll() converts a whole module |
util.promisify() converts one function |
| Extra helpers | map, filter, props, each, timeout, cancellation | all, allSettled, any, race only |
| Long stack traces | Yes, when enabled | Improved but shorter |
| Best for | Legacy callback libraries, concurrency helpers | New code, and anything using async await |
Choose native promises for new work, since they need no dependency and integrate directly with async await. Reach for Bluebird when a dependency still exposes callbacks only, or when its concurrency helpers, such as Promise.map with a concurrency limit, save a meaningful amount of code.
How to Handle Errors with Bluebird Promises
The example above has no failure path. If MongoDB is not running, or the collection name is wrong, the chain rejects and nothing is printed โ the process simply exits with no explanation. Every promise chain needs a terminal handler.
Bluebird supports .catch() for rejections and .finally() for cleanup that must run either way. It also supports typed catches, which handle one class of error while letting others propagate.
var Promise = require('bluebird'); var mongoClient = Promise.promisifyAll(require('mongodb')).MongoClient; var connection; mongoClient.connectAsync('mongodb://localhost/EmployeeDB') .then(function(db) { connection = db; return db.collection('Employee').findAsync({}); }) .then(function(cursor) { return cursor.toArrayAsync(); }) .then(function(docs) { docs.forEach(function(doc) { console.log(doc); }); }) .catch(Promise.TimeoutError, function(err) { console.error('The database did not respond in time.'); }) .catch(function(err) { // Any other rejection from any step above arrives here console.error('Query failed:', err.message); }) .finally(function() { // Runs on success and on failure, so the socket always closes if (connection) { connection.close(); } });
Three habits matter here. First, place .catch() at the end rather than after each step, because one terminal handler receives rejections from every preceding link in the chain. Second, use .finally() for releasing resources such as a database connection, since it runs on both the success and failure paths. Third, never leave a chain without a catch: an unhandled rejection terminates the Node process on current versions, and Bluebird will print an explicit warning about it beforehand. Enabling long stack traces during development with Promise.config({ longStackTraces: true }) makes the origin of a rejection far easier to locate.
Common Bluebird Promisify Errors and Fixes
Most Bluebird problems come from the promisified naming convention, or from mixing the callback and promise calling styles in the same chain, rather than from any fault in the library itself. Each symptom below names its cause and its fix.
- โconnectAsync is not a functionโ: the module was required directly instead of through
promisifyAll(), so no Async variants exist. Wrap the require call as shown above. - Calling the plain method and getting undefined:
connect()still expects a callback. Only the Async-suffixed copy returns a promise. - Passing a callback to an Async method: supply neither a callback nor
awaitand the promise resolves unobserved. Use one style per call, not both. - promisifyAll on an already promise-based library: harmless but pointless, and it produces confusing double-suffixed names. Check the library documentation first.
- Losing errors silently: a chain with no
.catch()hides the rejection reason until Node reports an unhandled rejection and exits. Always terminate the chain with a catch, even in short scripts.



