Full Content: Finding the Right Fit
Comparing 6 Popular Node.js Web Frameworks
Finding the Right Fit: Comparing 6 Popular Node.js Web Frameworks
Contents
- Overview
- Express
- Koa
- hapi
- restify
- Loopback
- Fastify
- Conclusion
Overview
With +62,000 stars on GitHub and more than a billion downloads since its introduction 10 years ago, Node.js is a major open source software project.
Node.js’s popularity can be attributed to its ease of adoption with JavaScript developers, a lightweight and performant core, and suitability for applications across platforms. This rapport with developers has created a thriving community of contributors, and an ecosystem of modules and frameworks to better facilitate secure, performant, and scalable development.
In this guide, we will look specifically at six Node.js web frameworks:
- Express
- Koa
- hapi
- restify
- Loopback
- Fastify
The following factors will be considered when looking at each web framework:
- Popularity and community involvement
- How easy is it to get started? Installation and basic ‘Hello World’ examples
- Performance
- Security
- A summary of advantages and disadvantages
All the code in this article can be found here and there.
Express
The ‘E’ in ‘MEAN Stack’, Express is a minimal and flexible Node.js web framework that provides a robust set of features for both web and mobile applications, focused on routing, writing middleware, and API development. Express is a clear winner in the downloads category, with over 8 million weekly downloads (second most is 300,000 weekly downloads).
Popularity and Community Involvement
GitHub Stars: 44,000+
npm weekly downloads: 8,000,000+
Number of contributors: 233
Closed Pull Requests: 844
The Express community meets regularly, and they communicate through their mailing list, Gitter, IRC channel, issues in GitHub, and the Express Wiki.
Installation
To install Express, navigate to your project’s root directory and run:
$ npm install express
Note: use the --no-save flag if you would like to use a package but not save it to your dependencies
express-generator is a package that will give you a basic Express project structure, and is great for getting started quickly.
Hello World app
Here is a basic Express app that listens on port 3000 and displays ‘Hello World!’ in the browser. For more detailed instructions, see the Express Installation guide.
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
Open http://localhost:3000/ in your browser to see the output and inspect the application.
To see more complex Express applications in action, here is a list of popular frameworks that are built on Express.
Performance
Express provides a thin layer of fundamental, un-opinionated web application features over Node.js, meant to provide some convenience with minimal hit on performance.
While comparing the benchmarking of these various frameworks, keep in mind that production demands are unique to each application, and when making performance decisions it is critical to establish baseline performance ranges based on an application’s specific demands.
All of this guide’s benchmarking information was captured with ab, the CLI for Apache Bench.
Over 5 tests the simple Express server averaged 6,301 requests per second.
Here are some application performance best practices from the folks at Express:
- Use gzip compression
- Don’t use synchronous functions
- Handle logging correctly (for debugging, use a special module like debug, for app activity use winston or bunyan
- Handle exceptions properly, using try-catch or promises.
- Ensure your app automatically restarts by using a process manager or use an init system like systemd or upstart.
- Run your app in a cluster. You can increase the performance of a Node.js app greatly by launching a cluster of processes (a cluster runs multiple instances of the app, distributing the load and tasks among the instances).
- Cache request results, so that your app does not repeat the operation to serve the same request repeatedly.
- Use a load balancer to run multiple instances of it and distribute the traffic, like Nginx or HAProxy.
- Use a reverse proxy that performs supporting operations on the requests. It can handle error pages, compression, caching, serving files, and load balancing among other things.
Security
Express publishes regular security updates. Since Node.js vulnerabilities directly affect Express, it is important to keep an eye on Node.js updates, and always check that you are using the latest stable version of Node.js.
Advantages
- Open source
- Express is the standard; plenty of community support and documentation
- Simple, minimalistic, flexible, and scalable
- Fast app development
- Fully customizable
- Low learning curve
- Easy integration of third-party services and middleware
- Ideal for smaller projects
Disadvantages
Although Express is a very convenient and easy-to-use framework, it has some minor drawbacks that may influence the development process.
- “Callback hell”
- Lack of opinionated architecture means organization needs to be very clear to avoid problems maintaining the code
- As your codebase size increases, refactoring becomes very challenging
- A lot of manual labor is required, since you need to create all endpoints
Koa
Koa was built by the same team behind Express, and aims to be more of a direct improvement on Node.js, rather than an augmentation of Node.js (like Express), creating a smaller, more expressive, and more robust foundation for web applications and APIs. By leveraging async functions, Koa frees developers from callback hell, and significantly improves error-handling. Koa does not bundle any middleware within its core, and it while providing a helpful suite of methods.
Popularity and Community Involvement
GitHub Stars: 26,000+
npm weekly downloads: 300K+
Number of contributors: 175
Closed Pull Requests: 589
You can join G+ koa Community, mailing list, contribute to Koa’s repo, join koa slack, or start a discussion in hashnode.
Installation
To install, navigate to your project’s root directory and run:
$ npm install koa
Note: Koa requires Node.js v7.6.0 or higher for ES2015 and async function support.
Hello World app
Here is a basic Koa app that listens on port 3000 and displays ‘Hello World!’ on the browser. For more detailed instructions, see the Koa application guide.
const Koa = require('koa');
const app = new Koa();
app.use(async ctx =>
{
ctx.body = 'Hello World!';
});
app.listen(3000);
A Koa Context (ctx in the code block above) is an abstraction that wraps around node’s request and response objects to facilitate development and control.
Note: ctx.req and ctx.res are node request and response objects, respectively, whereas ctx.request and ctx.response are Koa request and response objects, respectively.
Performance
Koa is free of any middleware, routing, or common convenience features like sending files, keeping its core extra light and performant.
Over 5 tests the simple Koa server averaged 8,706 requests/second.
Security
Koa relies on external middleware to maintain secure applications. Some popular security middleware for Koa are koa-helmet, koa-ip-filter, and koa-authz.
As always, it is important to keep an eye on Node.js updates, and always check that you are using the latest stable version of Node.js.
Advantages
Koa improves interoperability, robustness, and makes writing middleware much more enjoyable.
- Open source
- Maintains a small footprint, as no middleware are bundled, just 550 lines of code
- Smooth user experience
- Promises-based control flow
- Better error handling through try/catch
- Cleaner, more readable async code
Disadvantages
- The open source community around Koa is relatively small
- Not compatible with conventional Express middleware
- Writing common middleware from scratch
hapi
hapi is a rich, configuration-driven framework for building applications and services, with an emphasis on addressing concerns for big projects and teams. It enables developers to focus on writing reusable application logic instead of spending time building infrastructure.
Popularity and Community Involvement
GitHub Stars:11,000+
npm weekly downloads: 250K+
Number of contributors: 184
Closed Pull Requests: 1,182
You can join slack channel, visit the community page, community governance page and follow them on twitter to keep updated with the latest news.
Installation
To install, navigate to your project’s root directory and run:
$ npm install hapi
Hello World app
Here is a basic hapi app that listens on port 3000 and displays ‘Hello World!’.
'use strict';
const Hapi = require('@hapi/hapi');
// Create a server with a host and port
const server = Hapi.server({
host: '127.0.0.1',
port: 3000
});
// Add the route
server.route({
method: 'GET',
path: '/',
handler: function(request, h) {
return 'Hello World!';
}
});
// Start the server
const start = async function() {
try {
await server.start();
} catch (err) {
console.log(err);
process.exit(1);
}
console.log('Server running at:', server.info.uri);
};
start();
Add the code snippet above to your project’s point of entry (I used ‘index.js’), and run node index.js to start the server. Navigate to ‘localhost:3000/’ to check for ‘Hello World!’ in the browser.
Performance
To sum hapi’s performance up neatly, here is what Joel Chen from WalmartLabs, where hapi was developed, had to say in an article about optimizing hapiJS:
“Hapi is a framework focus[sic] on providing an infrastructure for developing solid business applications. It makes tradeoffs on “benchmark performances” for features such as strict checks and validations that are very useful when hundreds of developers are working on the apps.”
Here is a humorous and well-informed perspective on benchmarking from Eran Hammer, the creator of hapi.js.
Over 5 tests the simple Hapi server averaged 3,703 requests/second.
Security
Different hapi-specific plugins can help to improve hapi security, here are a few from a more detailed article by Synopsys:
- Crumb: Anti cross-site-request-forgery (XCSRF) token generation and validation plugin.
- Joi: Object schema description language and validator for JavaScript objects.
- Hapi-rbac: Allows developers to implement role-based access controls easily.
- Blankie: Allows developers to set the Content-Security-Policy header directives easily and discriminately.
- Cryptiles: Provides general purpose cryptographic utilities for random number generation, encryption, hashing and fixed-time comparisons of hashes that are based on the Node.js crypto library.
Advantages
- Open source
- Build scalable APIs quickly
- Richer out-of-the-box request handling
- An extensive plugin system
- Good documentation coverage
- Suitable for large projects
Disadvantages
- Higher learning curve for those experienced with Express
- Developers need to figure out the code structure on their own.
- “Locks” developers into using hapi-specific modules and plugins
- Endpoints are created manually and must be tested manually
- Refactoring is manual
restify
According to their README, restify is a Node.js framework that uses connect-style middleware for building RESTful APIs.
Trusted by big tech brands like npm, Netflix, and Joyent, restify has been in the ecosystem since 2011, and, compared to Express, offers better controls over lower-level concerns such as latency and other performance issues.
Popularity and Community Involvement
GitHub Stars: 9,000+
npm weekly downloads: 99,000+
Number of contributors:188
Closed Pull Requests: 752
You can reach out about issues or bugs on GitHub, join their mailing list, and follow them on twitter to keep updated with the latest news.
Installation
To install, navigate to your project’s root directory and run:
$ npm install restify
Hello World app
Here is a basic restify app that listens on port 3000 and displays ‘Hello World!’.
var restify = require('restify');
var server = restify.createServer();
function respond(req, res, next) {
res.send('Hello World!');
next();
}
server.get('/', respond);
server.head('/', respond);
server.listen(3000, function() {
console.log('You are listening at %s', server.url);
});
Performance
In this article’s simple benchmarking context, restify performs the best of the six frameworks, with an average of over 9,000 requests/s. This is significant as it has more out-of-the-box functionality than Express, yet maintains a performance edge.
Over 5 tests the simple restify server averaged 9,573 requests/second.
Security
Restify has no known security issues. A well-populated middleware community provides solutions to standard security concerns like authentication and CORS.
Advantages
- Open source
- Easy to pick up for Express developers
- A lot of functionality for a small footprint
- A performant, scalable framework capable of handling high request loads
Disadvantages
- Manual endpoint creation and testing
- Lacks a clear structure
- Can become difficult to maintain
Loopback
Based on Express, Loopback is a Node.js framework for building APIs that focuses on “convention over configuration,” and providing developers some of the out-of-the-box ‘magic’ more commonly associated with frameworks like Ruby on Rails.
Written in TypeScript/ES2017, Loopback ensures concurrency with the latest features, such as async and decorators. Loopback is maintained by IBM’s StrongLoop, who are core supporters of Node.js and Express, giving it a huge network of experience, and an eye on convenience for large scale development projects.
Popularity and Community InvolvementGitHub Stars: 12,000+
npm weekly downloads: 28,000+
Number of contributors: 103
Closed Pull Requests: 1,026
For questions and general information, you can head over to Loopback’s Developer Resources, including their blog, tutorials, and other helpful links. You can use StrongLoop’s twitter to reach out about #loopback. Join the conversation on Gitter or their Google Group.
Installation
Install the Loopback 4 CLI globally. You might have to prefix with sudo to grant permission:
npm install -g @loopback/cli
Hello World app
Once the LoopBack 4 CLI has installed, we have to create a new application project. We will call this application ‘app’:
$ lb4 app
You will be prompted with some questions to pre-configure the project. Answer the prompts as follow:
Once complete, change directories and start up the server:
$ cd getting-started
$ npm start
Check the server by visiting http://127.0.0.1:3000/ping in your browser.
Note: It’s worth pointing out that we now have two functional routes, ‘/’ and ‘/ping’, and we haven’t written any code! Features like this speed up development, sometimes at the cost of flexibility and performance.
To give us a ‘Hello World!’ display we will have to add a new controller:
$ lb4 controller
More prompts will follow. Enter ‘hello’ for the class name prompt. For the second prompt, choose to make an ‘Empty Controller.’
Note: For the second prompt, you can also choose ‘REST Controller with CRUD functions,’ but you will be required to set up additional resources that this guide will not go in to (though LoopBack’s tutorials do).
You can paste the following code block into the newly created /src/controllers/hello.controller.ts:
import { get } from '@loopback/rest';
export class HelloController {
@get('/hello')
hello(): string {
return 'Hello world!';
}
}
Visit http://127.0.0.1:3000/hello to see ‘Hello world!’
Performance
Loopback performed relatively well in the benchmarking tests.
Over 5 tests the simple Loopback server averaged 9,074 requests/second.
Security
Staying up to date with the Node.js releases and the latest version of LoopBack is foundational to a secure application. To update LoopBack you run the installation command npm install -g @loopback/cli.
LoopBack’s very good documentation provides a lot of clear and helpful information for handling security issues like authentication and authorization.
Advantages
- Open source
- Fully-featured, with lots of out-of-the-box functionality and “magic”
- Use of TypeScript enables easier automation of validations and testing
- Opinionated architecture is helpful for larger development teams
- Documentation is clear and thorough, including detailed How-To material
- Full-time team of support staff and engineers
- Built-in models, ORM/ODM support, and access-level controls
- Speedy database connection across a range of database providers
Disadvantages
- Potentially steep learning curve for developers
- Comes with a lot of files
- Opinionated architecture can feel like bloat at first
Fastify
Per the Fastify website, “Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. It is inspired by Hapi and Express and as far as we know, it is one of the fastest web frameworks in town.”
Introduced in 2017, Fastify is a newer player in the Node.js framework community, and is optimized for HTTP APIs that handle JSON data.
Popularity and Community Involvement
GitHub Stars: 11,000+
npm weekly downloads: 39,000+
Number of contributors: 166
Closed Pull Requests: :1,034
You can reach out about issues or bugs on GitHub or their help page, join the conversation on Gitter, and follow them on twitter to keep updated with the latest news.
Installation
To install, navigate to your project’s root directory and run:
$ npm install fastify
Hello World app
Now we will make a simple Fastify app that listens on port 3000 and displays a JSON object, { Hello: “World!” }. This code sample will make use of async-await.
const fastify = require('fastify')
fastify.get('/', async (request, reply) =>
{
return {
hello: 'world'
}
})
const start = async () =>
{
try {
await fastify.listen(3000)
fastify.log.info(`server listening on ${fastify.server.ad-
dress().port}`)
} catch (err) {
fastify.log.error(err)
process.exit(1)
}
}
start()
Note: Fastify has a generator function with its CLI if you want to get up and running with a bit more to explore.
Performance
If you look at their benchmarking numbers, Fastify is actually the fastest Node.js framework.
Fastify’s benchmarking repo is a great resource for curious Node.js developers looking to compare frameworks’ code, quality, and general feel.
Here is how Fastify did under our benchmarking conditions:
Over 5 tests the simple Fastify server averaged 8,854 requests/second.
Security
Taking a lead from hapi.js, Fastify has a rich plugin ecosystem of core and community plugins. Core plugins such as fastify-auth, fastify-cors, fastify-jwt, and fastify-helmet provide most of the needed security and validation. The core support for these features also seems to be sufficient as the community plugins don’t cover this terrain as much.
Advantages
Disadvantages
Conclusion
This review has no intention of deciding on “one framework to rule them all”, but rather highlighting the use and general characteristics of six of the most common and compelling Node.js web frameworks to make finding the software that best aligns with your application needs. With that said, let’s look at each of the criteria with all six frameworks in mind. As a reminder, the criteria were:
In the Popularity and Community Involvement category, the clear winner is Express.js. With over 7,000,000 more weekly downloads than the nearest competitor, it truly stands alone as the standard abstraction of Node.js’s http module. This means there is an abundance of both core and community documentation, troubleshooting support, video tutorials, and other resources for Express-based applications.
Koa, hapi, Restify, all fall between 100,000 and 300,000 weekly downloads, with enthusiastic communities of developers.
Fastify and Loopback have a lot less engagement, and this was reflected in the auxiliary resources we were able to find online. That being said, both have good core documentation.
When it came to Getting Started, five out of the six were fairly straightforward: install the dependency, create a server file, run with node. Loopback, however, required several more steps, and locks you into its opinionated manners almost immediately. This felt burdensome for a simple example, but if our example had been creating a whole suite of RESTful routes, it would have stood out as the fastest and easiest, as Loopback has baked in a lot more ‘automagic’ than any of the other frameworks.
We compared the Performance of the six frameworks with Apache Bench, a CLI tool for simple load testing. hapi.js was the ‘slowest’, averaging about 3700 requests/second, while Koa, restify, Loopback, and Fastify averaging between 8700 and 9500 requests/second. Express.js landed somewhere in the middle with about 6,300 requests/second. At the risk of sounding redundant, production demands are unique to each application, and when making performance decisions it is critical to establish baseline performance ranges based on an application’s specific demands.
There were no isolated or unique Security concerns among the six frameworks. As all six ‘sit’ on top of Node.js, it is important to keep an eye on Node.js updates, and always check that you are using the latest stable version of Node.js. Aside from that, making sure to keep dependencies up to date, using the right plugins, and staying focused on fundamental security concerns like headers will help keep your applications secure with any of these frameworks.
To summarize the Advantages and Disadvantages, let’s focus on what each framework seems best at accomplishing (with associated downside):
Framework | Big Pro | Big Con |
---|---|---|
Express | Simple, fully customizable, low learning curve | Constantly re-inventing the wheel |
Koa | Even lighter than Express | Not compatible with Express middleware |
hapi | Great out-of-the-box functionality | Potentially high learning curve |
restify | Lots of functionality with a small footprint | Manual endpoint creation and testing |
Loopback | Generate RESTful APIs in a flash | A lot of code you might not need |
Fastify | Highly extensible and performant | Small team of maintainers |