• Home
  • blog
  • A Side-by-side Comparison of Express, Koa and Hapi.js

A Side-by-side Comparison of Express, Koa and Hapi.js

If you’re a Node.js developer, chances are you have, at some point, used Express.js to create your applications or APIs. Express.js is a very popular Node.js framework, and even has some other frameworks built on top of it such as Sails.js, kraken.js, KeystoneJS and many others. However, amidst this popularity, a bunch of other frameworks have been gaining attention in the JavaScript world, such as Koa and hapi.

In this article, we’ll examine Express.js, Koa and hapi.js — their similarities, differences and use cases.


Let’s firstly introduce each of these frameworks separately.


Express.js is described as the standard server framework for Node.js. It was created by TJ Holowaychuk, acquired by StrongLoop in 2014, and is currently maintained by the Node.js Foundation incubator. With about 170+ million downloads in the last year, it’s currently beyond doubt that it’s the most popular Node.js framework.


Development began on Koa in late 2013 by the same guys at Express. It’s referred to as the future of Express. Koa is also described as a much more modern, modular and minimalistic version of the Express framework.


Hapi.js was developed by the team at Walmart Labs (led by Eran Hammer) after they tried Express and discovered that it didn’t work for their requirements. It was originally developed on top of Express, but as time went by, it grew into a full-fledged framework.

Fun Fact: hapi is short for Http API server.


Now that we have some background on the frameworks and how they were created, let’s compare each of them based on important concepts, such as their philosophy, routing, and so on.

Note: all code examples are in ES6 and make use of version 4 of Express.js, 2.4 of Koa, and 17 for hapi.js.


Express was built to be a simple, unopinionated web framework. From its GitHub README:

The Express philosophy is to provide small, robust tooling for HTTP servers, making it a great solution for single page applications, web sites, hybrids, or public HTTP APIs.

Express.js is minimal and doesn’t possess many features out of the box. It doesn’t force things like file structure, ORM or templating engine.


While Express.js is minimal, Koa can boast a much more minimalistic code footprint — around 2k LOC. Its aim is to allow developers be even more expressive. Like Express.js, it can easily be extended by using existing or custom plugins and middleware. It’s more futuristic in its approach, in that it relies heavily on the relatively new JavaScript features like generators and async/await.


Hapi.js focusses more on configuration and provides a lot more features out of the box than Koa and Express.js. Eran Hammer, one of the creators of hapi, described the reason for building the framework properly in his blog post:

hapi was created around the idea that configuration is better than code, that business logic must be isolated from the transport layer, and that native node constructs like buffers and stream should be supported as first class objects.

Starting a Server

Starting a server is one of the basic things we’d need to do in our projects. Let’s examine how it can be done in the different frameworks. We’ll start a server and listen on port 3000 in each example.


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

app.listen(3000, () => console.log('App is listening on port 3000!'));

Starting a server in Express.js is as simple as requiring the express package, initializing the express app to the app variable and calling the app.listen() method, which is just a wrapper around the native Node.js http.createServer() method.


Starting a server in Koa is quite similar to Express.js:

const Koa = require('koa');
const app = new Koa();

app.listen(3000, () => console.log('App is listening on port 3000!'));

The app.listen() method in Koa is also a wrapper around the http.createServer() method.


Starting a server in hapi.js is quite a departure from what many of us may be used to from Express:

const Hapi = require('hapi');

const server = Hapi.server({
    host: 'localhost',
    port: 3000

async function start() {
  try {
    await server.start();
  catch (err) {
  console.log('Server running at:',;


In the code block above, first we require the hapi package, then instantiate a server with Hapi.server(), which has a single config object argument containing the host and port parameters. Then we start the server with the asynchronous server.start() function.

Unlike in Express.js and Koa, the server.start() function in hapi is not a wrapper around the native http.createServer() method. It instead implements its own custom logic.

The above code example is from the hapi.js website, and shows the importance the creators of hapi.js place on configuration and error handling.

Continue reading %A Side-by-side Comparison of Express, Koa and Hapi.js%