One of the most popular frameworks in the Node world has been (and still is), Express. Express is a great framework; I was impressed enough to write a book about it. I’m pleased to announce that Express is dead. Wait, pleased? Yes, pleased. Not because I have changed my mind about Express, but because Koa has arrived, and Koa is the inevitable evolution of Express.
One of the reasons I am welcoming Koa with open arms is that if you know Express, and you know ES6 (aka Harmony aka ECMAScript 2015), you know Koa. This is no surprise, either: the author of Express, TJ Holowaychuk, is the man behind Koa. Koa and Express are so related, as a matter of fact, that I imagine it was a difficult decision not to simply make the next version of Express what Koa is. But there are advantages to starting fresh, and nothing seems out-of-place in Koa, so I feel that TJ has made good use of this tabula rasa.
I don’t know why TJ named this project Koa. Certainly not after the unfortunate acronym “Kampgrounds of America“; probably after the Acacia koa, a flowering tree native to the Hawaiian islands. According to Wikipedia, the word koa in Hawaiian means “brave, bold, fearless, or warrior.” Yeah, let’s go with that.
Many intro programming courses trot out the shopworn metaphor of a recipe — for example, a recipe for egg salad. The idea is that you have a list of ingredients (inputs), the recipe itself (the program), and you’re left with egg salad (the output). This metaphor usually makes it explicit that the instructions in the recipe are linear: step 1, step 2, step 3, etc. It’s a reasonable enough metaphor — accessible in that most people have cooked something at one point in their life. However, an experienced cook knows that the reality of cooking is something different altogether. If you were to only do things in sequence, it would take you four times as long to make that egg salad. Key example: while the eggs are boiling, you can be chopping the celery and green onions. Recipes are usually written such that people can generally figure out these time-saving parallel actions themselves. Programming languages are notoriously poor at “figuring out what you mean,” and have to be explicitly told when things can be done in parallel, and when it’s okay to bring “ingredients” together: enter asynchronous programming.
Callback hell even spawned its own memes:
Which brings us to the conditions that were present when TJ wrote Express. Express was all callbacks, and you could use promise libraries to mitigate callback hell. It was a good time, and Express was loved by many (including myself).
What ES6 brings to the table — generators — completes the picture. Generators, along with generator runners (or generator engines), callbacks, and promises finally provide all the tools you need to do something you couldn’t do without generators: program asynchronously in a synchronous fashion.
Wait, what? All that work to get back where we started (synchronous programming)? Not exactly. Generators don’t get rid of asynchronous programming: they make it possible to program in a synchronous manner (which is undeniably easier), and the messy details of asynchronous execution are hidden away from sight. The fact is, between user interaction (which is inherently asynchronous) and integrating disparate systems and services (also asynchronous), you can’t “wish away” asynchronous programming. But you can make it easier to manage.
And there is a danger in “abstracting away” asynchronous behavior behind generators and generator runners: while it frees us from the specter of locking up the entire program while you’re waiting on some asynchronous event, it does make it easy to make things synchronous that should be run in parallel. So its still important to know what’s going on, and the interaction between generators, generator runners, promises, and callbacks (and a new actor on the scene, a specific type of callback called a “thunk”).
So back to Koa. Just as Express’s handling of HTTP requests was done a pipeline of callbacks, Koa handles HTTP requests with a pipeline of generators, and serves as a generator runner (it actually uses a generator runner called “co“).
The best thing about building web apps with Koa is how pleasant it is. Once you learn the handful of techniques necessary to deal with asynchronous execution with Koa’s generator runner, you’ll wonder why you ever put up with callback hell.
Happily, the packaged functionality you came to love in Express is being ported over to Koa at a remarkable rate. To date, I haven’t thought “oh, I need express-X” and didn’t find a corresponding “koa-X” package (and it’s easy enough to adapt Express-style middleware to Koa love).
If you’re a programmer, and you want to know more about generators, I recommend Kyle Simpson’s excellent article The Basis of ES6 Generators. If you want to give Koa a spin, the Koa website has most of the important information. However, it’s not what I would call “comprehensive documentation” yet, and if you’re not already familiar with Express, you might be a little lost (in which case, you should read my book , then come back to Koa).