В последнее время активно использую связку
Express +
exa.
По сути дела первый - стандарт в Nodejs разработки (так или иначе ноги у многих фреймворков растут из него. Да и на текущий момент он самый популярный);
А Exa избавляет Express от callback hell за счет ES7
async/await или ES6 генераторов. При этом как я понял он не лезет в сам Express и не меняет его, а просто примешивает асинхронные методы для роутеров.
И получается что-то типо того:
'use strict';
const exa = require('exa');
const express = require('express');
const mongoose = require('mongoose');
const app = exa(express()); // Примешивание методов
const User = mongoose.model('User');
app.$get("/", function * (req, res) {
const users = yield User.find({}).exec();
res.send(users);
});
app.use(function (err, req, res, next) {
// Все ошибки свалятся сюда
res.statusStatus(500);
});