The complete guide to Node.js frameworks

A quick tour of the best MVC frameworks, REST API frameworks, full-stack frameworks, and other handy libraries for Node.js

The complete guide to Node.js frameworks
Thinkstock

Node.js is a JavaScript runtime, built on Chrome’s V8 JavaScript engine, that’s suitable for implementing both desktop and server apps. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient compared to threaded servers, such as Apache, IIS, and your typical Java server.

While you can implement a web server or app entirely in plain Node.js code, a framework can greatly reduce the amount of code you need to write. In this guide, we survey the gamut of frameworks available to the Node.js developer.

We start with minimalist Sinatra-like frameworks such as Express, move to more opinionated Rails-like frameworks such as Sails.js, then on to full-stack frameworks with scaffolding and persistence libraries such as Meteor. Finally, we cover REST API frameworks such as LoopBack, and a few “other” libraries for purposes that fall outside our main categories (like ORM, IoT, and static site generation).

Note that the classifications are not well separated. There are several frameworks that could be considered to belong to multiple categories.

Note there are more Node.js MVC projects than I have listed here. In some cases I eliminated projects that are no longer active. In others, I eliminated frameworks that never attracted significant developer interest despite continuous activity. My goal is not to tell you about every possible project, but rather to help you to identify projects that might be worth your evaluation time.

MVC frameworks for Node.js

MVC (model-view-controller) is a paradigm intended to partition the functionality of a desktop or web application cleanly. The model manages the underlying data structure. The view manages what is shown to the user. And the controller manages what happens in response to user requests.

Rails is a full-featured, “opinionated” MVC-based web framework created in 2004 by David Heinemeier Hansson (aka DHH) to give Ruby a way to establish a web presence. Rails assumes that you are using a database, values convention over configuration, and scales well. The Rails-like Node.js MVC frameworks are the ones that are full-featured.

Sinatra is a bare-basics, less-opinionated MVC-based web framework that was created in 2007 by Blake Mizerany and is currently maintained by Konstantin Haase. Sinatra took the opposite approach of Rails in that it has only what you need for a web application, basically routes to put your app on the web with a DSL (domain specific language) over a “rack” layer. Rack is an abstraction layer based on the Node.js EventEmitter, and provides a simple way of dealing with cluster support.

The Sinatra-like Node.js MVC frameworks are the ones that start simple and let you add components as needed. Many of the Sinatra-like Node.js MVC frameworks do, in fact, value convention over configuration, so the line between these and the Rails-like frameworks isn’t always clear.

Sinatra-like MVC frameworks for Node.js

Diet

Diet bills itself as a tiny, modular Node.js web framework that is good for making fast, scalable apps and APIs. A basic Diet server looks a great deal like a basic Express server:

// Create an app
  var server = require(‘diet’)
  var app = server()
  app.listen(‘http://localhost:8000’)

// When http://localhost:8000/ is requested, respond with “Hello World!”
  app.get(‘/’, function($){
  $.end(‘Hello World!’)
  })

Diet has a structure that supports virtual hosting without any additional modules or configuration. Diet server instances function as virtual hosts. Just have them listen on different ports.

Routing in Diet not only handles specific paths with anonymous functions, as in the app.get() example above, but can also establish a pipeline of middleware:

// Register middleware functions for the upload path
  app.post(‘/upload/picture’, upload, crop, save, finish)

Node.js by default has two arguments, request and response, when creating a HTTP(s) server using http.createServer(). Diet combines these two objects into a single signal object that is represented by a dollar sign $. You can see in the app.get() sample above that the signal object is the argument for the function that handles get requests on the root path. Diet also supports Node.js modules and can use them as middleware, as shown in the app.post() example above.

Express

Express is a minimal and flexible Node.js web application framework, providing a robust set of features for building single, multi-page, and hybrid web applications. The Express API deals with the web application, HTTP requests and responses, routing, and middleware. As of Express 4.x, the supported middleware for Express resides in a number of separate repositories, listed in the Connect repo.

Several forks of and add-ons for Express have surfaced, including Locomotive, Hapi, and Koa. Koa was created by one of the main contributors to Express.

Even though Express is older and has a larger footprint compared to its scions, it still has a larger community and more stability than any of them. I constantly see Express incorporated into other frameworks and tools without comment, as if it were the only possible choice for building a web server on Node.js.

// create an express application

const express = require(‘express’)
const app = express()

app.get(‘/‘, function (req, res) {
res.send(‘Hello world!’)
})

app.listen(3000, function () {
console.log(‘Example app listening on port 3000!)
})

Flatiron

Flatiron is part of the Nodejitsu Node tool suite. The authors consider Flatiron to be two things: First, an initiative to build a collection of decoupled tools with a high standard of quality and performance. And second, a full-stack web application development framework that packages these tools together to make isomorphic and stream-based application development easier.

Flatiron is Sinatra-like in that all you need to do to use it as a web server is to require it, instantiate an app, and use the http plugins, set up some routes, and start the app, as shown in the screenshot below.

Other pieces of the suite complement flatiron’s functionality. For example Broadway exposes a simple “plugin” API, substituting for the inversion of control registration used by other Node MVC frameworks. Union is a hybrid buffered/streaming middleware kernel, which is backward-compatible with Connect. Union is the piece that supplies the http plugin.

// create a flatiron application

var flatiron = require(‘flatiron’), 
  app = flatiron.app;

app.use(flatiron.plugins.http);

app.router.get(‘/‘, function () {
  this.res.writeHead(200, { ‘Content-Type’: ‘text/plain’ });
  this.res.end(‘Hello world!\n’);
});

app.start(8080);

Hapi

Hapi is a simple-to-use, configuration-centric framework with built-in support for input validation, caching, authentication, and other essential facilities for building web and services applications. Hapi enables developers to focus on writing reusable application logic through a highly modular and prescriptive approach. Hapi was developed by Walmart Labs and is a good choice for large teams and large projects.

Hapi was originally built on top of Express, but was later redesigned to be stand-alone. As its creators put it, Hapi was built with the idea that configuration is better than code and that business logic must be isolated from the transport layer. In the example below, notice how clear and clean the configuration of server routes appears in the code.

// create a hapi server

var Hapi = require(‘hapi’);
var server = new Hapi.Server(3000);

server.route([
  {
    method: ‘GET’,
    path: ‘/api/items’,
    handler: function(request, reply) {
      reply(‘Get item id’);
    }
  },
  {
    method: ‘GET’,
    path: ‘/api/items/{id}’,
    handler: function(request, reply) {
      reply(‘Get item id: ’ + request.params.id);
    }
  },

Koa

Koa is a newer web framework designed by the team behind Express, but independent of the Express code. Koa aims to be a smaller, more expressive, and more robust foundation for web applications and APIs. Koa uses ES6 generators for middleware rather than Node.js callbacks. The following is a “Hello, World” Koa application using a generator, which does a yield next to pass control to the next generator:

var koa = require(‘koa’);
var app = koa();

// x-response-time
app.use(function *(next){
  var start = new Date;
  yield next;
  var ms = new Date - start;
  this.set(‘X-Response-Time’, ms + ‘ms’);
});

// response
app.use(function *(){
  this.body = ‘Hello World’;
});

app.listen(3000);

There’s a difference between middleware generators as used by Koa and callbacks as used by Express and Connect. Connect’s implementation simply passes control through series of functions until one returns, while Koa yields “downstream,” then control flows back “upstream.”

In the example above, the x-response-time “wraps” the response generator, with the yield next statement marking the call. Yielding is more flexible than explicit function calls, as it makes it easy to insert another generator into the sequence, for example a web logger between the timer and the response.

Locomotive

Locomotive is a web framework for Node.js that supports MVC patterns, RESTful routes, and convention over configuration (like Rails), while integrating seamlessly with any database and template engine. Locomotive builds on Express and Connect.

Locomotive adds to Express some Ruby-on-Rails-like structure, which you can see in the image below. Locomotive views are often embedded JavaScript (html.ejs) files, as shown here, but Locomotive also supports Jade and the other compliant template engines for Express. The REST functionality is controlled by routes, as is usually the case in Express-based servers. You can use whatever database and ORM layer you’d like with Locomotive. The guide demonstrates using MongoDB with Mongoose, as well as using Passport for user authentication.

nodejs locomotive IDG

Total.js

Total.js is a full-featured server-side framework for Node.js, written in pure JavaScript, similar to PHP’s Laravel or Python’s Django. The Total.js platform is a collection of libraries, packages, and completed products built with Total.js.

Total.js is more Sinatra-like than Rails-like in that it’s modular, and because it is agnostic about IDEs, databases, and client-side frameworks. A minimal Total.js web server can be implemented with the following code:

require(‘total.js’);

F.route(‘/’, function() {
    this.plain(‘total.js is really good!’);
});

F.http(‘debug’);

Related video: Node.js tips and tricks

Rails-like MVC frameworks for Node.js

Adonis

Adonis is a MVC framework for Node.js built around practical use cases. It supports dependency injection and has a lean IoC (inversion of control) container to help you resolve and mock dependencies. Adonis provides a CLI tool to scaffold and generate a project with all required dependencies.

Among the features of Adonis are an ORM (Lucid) ans implementation of the active record design pattern; an authentication layer bundled with sessions, JWT, basic authentication, and personal API tokens; and an implementation of controllers as ES2015 classes. ES2015 generators eliminate the messy callbacks common in older JavaScript. The following code fetches all of the users from the database and returns them as JSON:

const Route = use(‘Route’)
const User = use(‘App/Model/User’)

Route.get(‘/’, function * (request, response) {
  const users = yield User.all()
  response.json(users)
})

CompoundJS

The formula behind CompoundJS is Express + structure + extensions. Here structure is the standard layout of directories, and extensions are Node.js modules that add functionality to the framework. The goal is to provide an obvious and well-organized interface for Express-compatible application development. This means that everything that works with Express will work with CompoundJS.

You can generate skeleton CompoundJS apps from the CLI:

npm install compound -g
compound init todo-list-app
cd todo-list-app && npm install
node .

The site listens on http://localhost:3000/ by default. You can go on to add scaffolding based on the models with the compound generate scaffold command.

Geddy

The Geddy framework implements MVC for Node.js in an extremely Rails-like way, even down to the directory structure, the ability to open a REPL console in the context of the app, and a generator script you can use to create apps, resource scaffolds, or bare models and controllers. The scaffolding can optionally generate EJS, Jade, Handlebars, Mustache, and Swig templates.

The geddy jake command can run various Jake (JavaScript make) tasks in the context of the current app, with full access to the models. This is useful for ancillary tasks such as testing, initializing the development database, and listing routes.

Kraken

Kraken, a PayPal open source project, is a secure and scalable layer that extends Express by providing structure and convention, much like Locomotive. Though Kraken is the main pillar of its framework, the following modules can also be used independently: Lusca (security), Kappa (NPM Proxy), Makara (LinkedIn Dust.js i18N), and Adaro (LinkedIn Dust.js Templating).

1 2 3 Page 1
Page 1 of 3
How to choose a low-code development platform