Getting started with Koa.js

Express.js has long been the de facto Node.js web framework, and is generally the default choice for anyone looking to build a website or API server in Node these days. While node has great built in primitives for building web servers, frameworks provide features such as middleware and routing, which are needed by all but the simplest web servers. In this tutorial, I will show you how to get started with Koa, a new framework from some of the people who created Express.

Note: Examples take advantage of newer ES2015 syntax features found in Node.js v6, so make sure you are running the latest version, or are using Babel to support older versions.

First, there was Express

You’re probably familiar with Express. It uses callback-style request handlers, similar to many of the internal Node APIs:

This is great, but is well-known to lead to callback hell as your app grows:

A great solution for cleaning up callbacks is to use Promises. These are supported natively since at least Node v0.12.

However, as you can see, promises with Express still require a lot of boilerplate code, including remembering to catch errors and pass them to next().

Koa allows us to replace all this mess with a much cleaner syntax, using the new async/await features coming soon to a JavaScript engine near you:

What’s an async?

What is this magic? Async functions are simply syntactic sugar around promises. However, they allow us to write asynchronous code in a procedural style, and have some nice advantages for keeping variables in scope as well.

For example, the following two functions are equivalent:

Any errors thrown in an async function are returned as a rejected promise:

Finally, inside async functions, we can call await to wait for another promise-returning function, and assign the result to a local variable:

If you don’t quite understand this yet, don’t worry. Just remember that you can only use the await keyword inside an async function.

Babel in the mix

Async/await isn’t natively support in Node.js yet, even using the latest version (v6). To use them in our code, we need to configure Babel, a handy compiler which lets us run tomorrow’s JavaScript, today.

Babel uses a set of transforms to support each JavaScript feature. Many Babel tutorials are written for the browser (where you need to support ancient JavaScript engines), or older versions of Node, and suggest using the ES2015 preset. However, if you’re using Node v6, this is unnecessary since most features are supported natively. We’re just going to install two transforms:

  • async-to-generator (to support async functions)
  • es2015-modules-commonjs (to support the new module import syntax)

Let’s get started!

$ npm init -y # if you are starting a new project
$ npm install --save \
babel-cli \
babel-plugin-transform-async-to-generator \

Add the following to a .babelrc file in your project directory:

Babel needs to be required before any scripts which use new syntax. In a larger project, we would set up a bootstrap file to do this using babel-register, but for now the easiest method is to simply use babel-node on the command line.

$ babel-node server.js

Finally, we can Koa

We’re now ready to use Koa, with all its async/await glory. There are two things you should keep in mind when using Koa:

  1. The version of Koa which supports promises (v2) is currently in beta. It’s fairly stable, however the authors don’t want to release it until Node natively supports async/await without needing Babel. The current stable version uses ES2015 generators, and has a completely different syntax. In the meantime, be sure to install v2 of Koa and any middleware you use.
  2. Koa by itself is actually only a middleware handler (in this regard it is more similar to Connect than Express). For route handling, we need to pull in koa-router.

With these in mind, let’s install Koa!

$ npm install --save koa@next koa-router@next

Create a server.js in your project directory.

To run your server, use babel-node:

$ babel-node server.js

In another window, you can make a request to your server:

$ curl -i http://localhost:3000/adrian
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 15
Date: Wed, 27 Apr 2016 07:26:27 GMT
Connection: keep-alive
Hello, adrian!

Congratulations! You now have your first Koa server up and running. To really start seeing the benefits of async/await, we will need to use some other libraries which have asynchronous code (such as Sequelize or Mongoose). In a future tutorial, I will explain how to structure large Koa applications, and how to write super clean unit tests using async/await and Mocha. In the meantime, feel free to extend your Koa application, and try to integrate it with your favorite asynchronous libraries.