Running with Scissors: Koa2 and Vue.js

5 min Read Time

We love Koa at Gilt. (Hell, I love Koa.) Embarking on a new project, I wanted to try something that wasn’t React or Angular. After poking at the alternatives I landed on Vue.js. I picked up the sharpest pair of scissors I could find and started running.

The Chosen Tech

If you haven’t heard of Koa:

Koa is a new web framework designed by the team behind Express, which aims to be a smaller, more expressive, and more robust foundation for web applications and APIs.

Koa is Express without the bells and whistles from the factory. Koa is the stock car that you bolt aftermarket parts onto, based on your needs. It’s fast as hell. It’s small. It’s a dang joy to work with. Koa2 improves on performance and makes use of await/async patterns.

If you haven’t heard of Vue.js;

Vue is a progressive framework for building user interfaces. …Vue is designed from the ground up to be incrementally adoptable. …is focused on the view layer only, and is also perfectly capable of powering sophisticated Single-Page Applications.

Basically Vue.js takes the good parts from React, Angular, and Aurelia and bundles them into a single lib. Who want’s to go fast?. React folks won’t like it because there’s no JSX and there’s two-way binding. I dig it explicitly because I personally think JSX is an abomination, but more specifically that Vue.js uses <templates> which are very close to web components and will make that transition easy in the future, if and when wide-spread support for them ever drops. I digress.

Setting Up

It’s worth noting that we’re using Node v7, which supports most ES5 and a lot of ES6 syntax, with BabelJS thrown in to fill the gaps.


I always start my Koa projects with a few base modules: koa (duh), koa-router, and koa-static. koa-static allows you to specify and serve one or more directories as static assets - a necessity. koa-router typically handles app routes; that is to say the different endpoints for your app. The code is pretty straight forward, here’s a basic app.js:

'use strict';
import 'colors';
import Koa from 'koa';
import serve from 'koa-static';

const app = new Koa(),
  port = 3000;

  .listen(port, () => {
    console.log('Server Started ∹'.green, 'http://localhost:'.grey + port.toString().blue);

export default app;


To start off a project with Vue, we used vue-cli. That allows us to create boilerplate apps. Since we’re running with scissors here, we jumped right in and went with the simplest template.

$ vue init webpack-simple .

That gives us a basic (as in pumpkin spice latte) Vue app which displays a single page at index.html with a logo and some links. That also generates the App.vue file, which is the main “Vue file” for the app. All of that resides in src now. That’s all well and good, but what about that Webpack file created?

Enter Webpack

Getting a Vue app working right means bundling correctly. We use Webpack, but there are a lot of examples out there with Browserify if you prefer that. Webpack is a wonderful bundling tool and can perform a host of functions. So much so that it can be considered a full-fledged build tool. You’ll need a webpack.config.js file to kick things off:

And then you’ll need Webpack itself:

$ npm install webpack -g

You’ll note that we did a few things different with webpack.config.js, beyond what the vue-cli generated for us; moved assets to assets and introduced a Webpack Plugin to combine CSS in Vue files into one single CSS file to be served by Koa.

Tying it together

If you’re following our example and using Babel as well, you’ll need a Node entry point file to set Babel up for development. We named this index.js:


Assuming you have a solid .babelrc and your dependencies setup correctly, you’re ready to try running this beast. First, fire up Webpack and create your bundles:

$ webpack

Assuming everything succeeded, you’re ready to start the server:

$ node index

And you should see something like this in your console:

→ node index
Server Started ∹ http://localhost:3000

Hit that address in your browser and you should see the Vue demo app. How do you like them apples? I love ‘em.

Running With Machetes

We’ve conquered scissors, let’s get silly and run around with something larger and sharper - in a following post I’ll walk through using middleware with Koa2 to allow live development and Hot Module Reloading. That means you don’t have to restart your server to rebuild your bundles, and you see changes nearly instantly. It’s cool, right?


Originally published at on November 3, 2016.

Andrew Powell