Return Promises from Express middleware and route callbacks






No Maintenance Data Available




Size (min+gzip)




Type Definitions






Return Promises from Express middleware and route callbacks

Build Status

Allow your Express middleware and route callbacks to return a Promise. When a Promise is fulfilled, the result is placed on the res object for use in subsequent middleware. When a Promise is rejected or an error is thrown within one, the next function is called to invoke your error handling middleware.

Getting Started

var express = require('express');
var app = express(app);

var expressPromisify = require('express-promisify');

As seen above, pass your Express app to expressPromisify. This will modify the app.use and app.VERB methods for the given app. For more information, see the "How It Works" section below.

Middleware and route callbacks can be defined and added as usual, but now you can optionally return a Promise. (Note that if you do not return a Promise or respond to the request you will still need to call next to contine to the next middleware or route callback.)

In the following example, db.query returns a Promise that is fulfilled when the query's results have been retrieved. The end result is stored on res.result when a Promise is fulfilled.

function getUserFromDatabase(req, res) {
  return db.query('SELECT * FROM users WHERE id = ?', req.params.id);

function respond(req, res) {
  if (res.result) {
  } else {

app.get('/users/:id', getUserFromDatabase, respond);

The respond function in this example is sends a response with the result of the Promise as JSON or a 404 if the query ended up having no result. In a real-world application, this function might also handle responding with a different content type based on the request's Accept header. This is a good way to share common code with several routes in your application.


Result Property on res

The property on res in which the Promise result is stored can be changed. This may be useful if for some reason you already have a res.result property. For example, to use a property called "promiseResult" instead:

expressPromisify.resultProperty = 'promiseResult';

Custom Fulfillment and Rejection Handlers

You can supply your own fulfillment and rejection handlers by overriding the expressPromisify.fulfillmentHandler and/or expressPromisify.rejectionHandler methods.

These methods get passed req, res, and next when a Promise returned by middleware or a route callback is fullfilled or rejected, and return a function that is the fulfillment or rejection handler, respectively.

The example below shows a fulfillment handler that will automatically respond with the result of a Promise if it is a string, rather than placing the result on the res object.

expressPromisify.fulfillmentHandler = function(req, res, next) {
  return function(result) { // this is what will be passed to `then`
    if (typeof result === 'string') {
    } else {
      res[expressPromisify.resultProperty] = result;

Note the default fulfillment and rejection handlers will be replaced with your custom ones. As shown in the example, to continue placing results on res for non-string values, that logic must be included as part of the custom handler. Also remember to call next for cases where you will need to continue to subsequent middleware or route callbacks.

How It Works

The app.use and app.VERB methods on the Express app that is passed into the expressPromisify are proxied to "promisify" any middleware or route callbacks that are passed into them. When you add middleware or route callbacks with these replacement methods, the functions you pass into them will be proxied to:

  1. Execute the original function
  2. Check if it returns a Promise, and if so...
  3. Call the fulfillment or rejection function, depending on if the Promise was fulfilled or rejected

When using the default fulfillment and rejection handlers, the next function will automatically be called to continue to the next middleware or route callback, if any. If the Promise returned by the function is rejected, next is called with the rejection reason, typically an error, as its argument; your error handling middleware will receive this reason so it can be handled accordingly.

Rate & Review

Great Documentation0
Easy to Use0
Highly Customizable0
Bleeding Edge0
Responsive Maintainers0
Poor Documentation0
Hard to Use0
Unwelcoming Community0