What Is The Best Deno Web Framework?
Tags: deno, webdev, typescript, javascript
Published: 2020-06-15 21:46:22

> _Please note that as Deno develops rapidly in these early stages, several of these metrics may well become outdated! I encourage you to take this as an initial guide, and be sure to explore the repos themselves - some may have grown in popularity since! I will endeavor to keep some stats relatively current as indicated by dates in each section._ :smile:

One of the common use-cases for any language is it's HTTP server capabilities. Generally we tend to see communities for any given language converge on one or a few web frameworks which provide the best trade-offs of features vs performance and show signs of development maturity and backing.

Because Deno is so new it can be difficult to know which of the arising web server frameworks is the one to use! On just the [Deno Land third party modules page](https://deno.land/x) there are 18 hits for `web framework` and 33 hits for `server`.

In this article I have tried to review the majority of frameworks, across several key factors, to help you can make an informed decision about which is the best for you!

I encourage to also read to the end where I touch on some frameworks I didn't fully review as well as any suggestions made in the comments!

## Community

A healthy community around a framework really helps to make using a framework easier. As it is so early on it's not particularly easy to determine which frameworks have the best community, but we can potentially infer some sense from GitHub usage.

Here are some of the GitHub stats:

| Framework                                                       | Stars | Forks | Watches | Open Issues | Closed Issues |
| :-------------------------------------------------------------- | :---: | :---: | :-----: | :---------: | :-----------: |
| [Abc](https://github.com/zhmushan/abc)                          |  415  |  41   |   20    |      0      |      41       |
| [Ako](https://github.com/ako-deno/ako)                          |   13   |   0   |    5    |      2      |       2       |
| [Aqua](https://github.com/l2ig/aqua)                            |  39   |   4   |    1    |      1      |      14       |
| [Attain](https://github.com/aaronwlee/Attain)                   |  28   |   2   |    2    |      4      |      19       |
| [Denotrain](https://github.com/Caesar2011/denotrain)            |  64   |   10   |    3    |      1      |       9       |
| [Drash](https://github.com/drashland/deno-drash)                |  541  |  19   |   16    |      16      |      98       |
| [Fastro](https://github.com/fastrodev/fastro)                   |   41   |   2   |    4    |      1      |       6       |
| [Fen](https://github.com/fen-land/deno-fen)                     |  71   |   2   |    9    |      0      |       1       |
| [http_wrapper](https://github.com/lindsaykwardell/http-wrapper) |   2   |   1   |    1    |      2      |       1       |
| [Oak](https://github.com/oakserver/oak)                         | 2202  |  128  |   34    |      11      |      132      |
| [Opine](https://github.com/asos-craigmorten/opine)              |  121   |   7   |    8    |      6      |       15       |
| [Pogo](https://github.com/sholladay/pogo)                       |  259  |  24   |   13    |      7      |      16       |
| [Servest](https://github.com/keroxp/servest)                    |  576  |  33   |   13    |      3      |       10       |
| [Snowlight](https://github.com/trylix/snowlight)                |  12   |   0   |    3    |      0      |       0       |

_Table data correct as of 22 July 2020_

- Stars - These tend to give a reasonable impression of what other people in the community are using so can be a reasonable indicator of what is good. Take care though, early on in a new language what was there first tends to start off with the most stars, but isn't necessarily what is the best now!
- Forks - A high number of forks tend to indicate that people are actively using and/or contributing to a framework.
- Watches - A high number of people watching a repository means that there is a community actively interested in receiving notifications for it's development.
- Open Issues - A high number of open issues can indicate that a project is not being well maintained. If the total number of open and closed issues is very small then it can mean that people aren't really using the framework as they haven't been asking questions, suggesting features, finding bugs - maybe the project is perfect, but that's probably not the case!
- Closed Issues - A high number of closed issues means that the project is likely being well maintained (especially this early on with Deno, in older languages you can have a high number and the project be dead for some time!) and that the community is actively involved in raising queries, suggestions etc.

## Documentation

When you're looking to use a new module, the key to getting started easily is documentation. What is generally the most useful being a quick-start guide and some references that allow you to see example code. As you start to use the framework in a more serious and complicated app, this is then complimented with a fuller, but easy to search and navigate, set of API docs (i.e. documented arguments and return types breakdowns etc.) and use-case guides (which may be the code examples themselves!).

| Framework                                                       | Getting Started Example | Code Examples | Guides | Full API Docs |
| :-------------------------------------------------------------- | :---------------------: | :-----------: | :----: | :-----------: |
| [Abc](https://github.com/zhmushan/abc)                          |           ✅            |      ✅       |   ✅   |      ✅       |
| [Ako](https://github.com/ako-deno/ako)                          |           ✅            |      ❌       |   ❌   |      ❌       |
| [Aqua](https://github.com/l2ig/aqua)                            |           ✅            |      ❌       |   ✅   |      ❌       |
| [Attain](https://github.com/aaronwlee/Attain)                   |           ✅            |      ✅       |   ✅   |      ✅       |
| [Denotrain](https://github.com/Caesar2011/denotrain)            |           ✅            |      ✅       |   ✅   |      ❌       |
| [Drash](https://github.com/drashland/deno-drash) 🌟             |           ✅            |      ✅       |   ✅   |      ✅       |
| [Fastro](https://github.com/fastrodev/fastro)                   |           ✅            |      ✅       |   ✅   |      ❌       |
| [Fen](https://github.com/fen-land/deno-fen)                     |           ✅            |      ✅       |   ✅   |      ❌       |
| [http_wrapper](https://github.com/lindsaykwardell/http-wrapper) |           ✅            |      ✅       |   ✅   |      ❌       |
| [Oak](https://github.com/oakserver/oak)                         |           ✅            |      ✅       |   ✅   |      ✅       |
| [Opine](https://github.com/asos-craigmorten/opine)              |           ✅            |      ✅       |   ✅   |      ✅       |
| [Pogo](https://github.com/sholladay/pogo)                       |           ✅            |      ✅       |   ✅   |      ✅       |
| [Servest](https://github.com/keroxp/servest)                    |           ✅            |      ✅       |   ✅   |      ✅       |
| [Snowlight](https://github.com/trylix/snowlight)                |           ✅            |      ✅       |   ✅   |      ✅       |

_Table data correct as of 15 June 2020_

Most of the reviewed frameworks have reasonable documentation. Only some fall down in fully documenting their APIs, however with the likes of <https://doc.deno.land/> and the usage of TypeScript, it is still possible to understand Deno modules reasonably well even if not documented extensively by the authors.

A golden star shout-out to [Drash](https://github.com/drashland/deno-drash) which has some of the most [amazing documentation](https://drash.land/) - it has everything from getting started, to full API docs, diagrams of the internals and comprehensive tutorials in it's own dedicated website.

## Performance

When it comes to production servers, performance under load is critical to providing a good service for your customers / clients, and should always be a consideration when choosing a web server framework. Of course there is the trade-off between performance and rich features - generally frameworks that offer the greatest set of features out-of-the-box are slightly heavier and thus slower than those that are thin wrappers around the core / standard library. Always take care to pick the server that offers the best performance for your current and any potential future use-case.

To get a measure of performance I was going to write a set of benchmarks when I happened across [Fastro](https://github.com/fastrodev/fastro) which supports a full benchmarking capability! So credit must go [@ynwd](https://github.com/ynwd) (currently the sole contributor) for the benchmark code!

> **Note:** This benchmark is not wholly realistic and you should always take care to benchmark and measure performance for your particular use-case.

For each framework I wrote the minimal amount of code in order to start a server which would respond to a `GET` request to the root `/` path with a body of `"Hello Deno!"`. The performance was measured using the NPM package `autocannon` with commands similar to:

```bash
npx autocannon -c100 -j localhost:3000
```

This was performed using:

- Machine: `MacBook Pro, 2.3 GHz Intel Core i5, 8 GB 2133 MHz LPDDR3`
- Node: `12.18.0`
- Deno: `1.1.0`

Here are the results, sorted by average requests per second achieved (PHP and Python Flask results taken from [Fastro](https://github.com/fastrodev/fastro)):

| Framework                                                       |    Version     |  Avg RPS | Language |
| :-------------------------------------------------------------- | :------------: | -------: | :------: |
| Deno HTTP                                                       | 1.1.0 (0.57.0) |  20687.6 |   Deno   |
| Node HTTP                                                       |    12.18.0     |  19954.8 |   Node   |
| [Denotrain](https://github.com/Caesar2011/denotrain)            |     0.5.2      |    19022 |   Deno   |
| [http_wrapper](https://github.com/lindsaykwardell/http-wrapper) |     0.5.0      |  18172.8 |   Deno   |
| [Fastro](https://github.com/fastrodev/fastro)                   |     0.10.1     |    17808 |   Deno   |
| Fastify                                                         |     2.14.1     | 17538.55 |   Node   |
| [Drash](https://github.com/drashland/deno-drash)                |     1.0.5      |  16305.2 |   Deno   |
| [Aqua](https://github.com/l2ig/aqua)                            |     master     |  16235.2 |   Deno   |
| [Abc](https://github.com/zhmushan/abc)                          |   1.0.0-rc10   |  14316.4 |   Deno   |
| [Attain](https://github.com/aaronwlee/Attain)                   |     0.9.4      |  14095.2 |   Deno   |
| [Oak](https://github.com/oakserver/oak)                         |     4.0.0      |  13851.2 |   Deno   |
| [Pogo](https://github.com/sholladay/pogo)                       |     0.4.0      |  11137.6 |   Deno   |
| Express                                                         |     4.17.1     |  10747.2 |   Node   |
| [Fen](https://github.com/fen-land/deno-fen)                     |     0.8.0      |  9265.21 |   Deno   |
| [Opine](https://github.com/asos-craigmorten/opine)              |     0.8.0      |   8409.8 |   Deno   |
| [Snowlight](https://github.com/trylix/snowlight)                |     master     |     8360 |   Deno   |
| [Servest](https://github.com/keroxp/servest)                    |     1.1.0      |   7452.8 |   Deno   |
| [Ako](https://github.com/ako-deno/ako)                          |     master     |   6329.1 |   Deno   |
| PHP                                                             |     7.3.11     |   6055.9 |   PHP    |
| Python Flask                                                    |     1.1.2      |   528.21 |  Python  |

_Table data correct as of 15 June 2020_

Interestingly Deno's standard HTTP was actually faster (on my setup, in this benchmark - results may vary!) than LTS Node 12.18.0 _despite_ the [Deno benchmarks](https://deno.land/benchmarks) finding Node's HTTP server performance to generally be faster. It may be, even with the slightest complexity that we've added, that we're observing the impact of the far superior tail latency of Deno meaning over the course of several requests it's consistently fast, whereas Node can be far more volatile.

Standout Deno modules are [Denotrain](https://github.com/Caesar2011/denotrain) and [Fastro](https://github.com/fastrodev/fastro) which both support routers and middleware and are reasonably close to the speed of the raw Deno HTTP library. [http_wrapper](https://github.com/lindsaykwardell/http-wrapper) is also in the mix if you need a fast Router but don't require a middleware structure.

## Familiarity

Though you should embrace change and be comfortable adopting the best practices for a particular language, sometimes the easiest way to get off the ground is to find something that best matches a library you are currently using. This way you could migrate existing projects to take advantage of things like Deno's enhanced security, plugin support etc. with minimal overhead, and you and your team will all be able to develop and extend programs easily as the API is familiar.

In this section I have attempted to identify the inspiration behind these libraries and rank them by similarity to existing Node libraries:

### Express

1. [Opine](https://github.com/asos-craigmorten/opine) - Not only is Opine inspired by Express, it is directly ported from it meaning both the API and internals are very similar (if not exactly) to Express. [Disclaimer: I am the author!]
1. [Attain](https://github.com/aaronwlee/Attain) - Attain supports an Express like middleware and Router API, with a few differences. Each handler is passed an [Oak](https://github.com/oakserver/oak) `Request` object and a `Response` object which offers several of the Express response APIs.
1. [Servest](https://github.com/keroxp/servest) - Another Express inspired HTTP server framework, Servest has many similar APIs to Express, though some named slightly differently. Unlike Express it's built in request object has methods for the parsing of requests, and also supports request filtering in it's handler API. It also has a logger built-in which one must configure to prevent from logging every request at `INFO` level.
1. [Snowlight](https://github.com/trylix/snowlight) - Snowlight is inspired by Express and much of it's API is taken directly from Express. It has some subtle differences such as the addition of a `app.group()` method allowing you to mount of shared middlewares onto a router for a specific path and lacks some of the less common response APIs etc.
1. [http_wrapper](https://github.com/lindsaykwardell/http-wrapper) - A minimal wrapper around the Deno HTTP standard library with a Router inspired by Express.
1. [Aqua](https://github.com/l2ig/aqua) - Router and middleware loosely mirrors the Express API.

### Koa

1. [Oak](https://github.com/oakserver/oak) - Oak was inspired by Koa and supports a reasonably rich context driven middleware API that mirrors Koa.
1. [Denotrain](https://github.com/Caesar2011/denotrain) - Although it states the library is inspired by Express, I have opted to list it under the Koa section because of it's use of a context like object instead of the connect style `(req, res, next)` middleware API. It does differ from Koa however in that responses are returned from route handlers and there is no `next()` for middleware.
1. [Ako](https://github.com/ako-deno/ako) - Ako aims to port Koa to Deno, and thus may eventually become the best option for users who wish to port their applications over to Deno. At the moment however it has very limited documentation so it hasn't been easy to ascertain how much it mirrors the Koa API - I recommend you certainly consider it for Koa like Deno applications as it may be that it plans to simply use the Koa docs as it's documentation!

### Fastify

1. [Fastro](https://github.com/fastrodev/fastro) - Inspired by Express, Nest & Firebase, but mostly takes it's API from Fastify.

### Hapi

1. [Pogo](https://github.com/sholladay/pogo) - Pogo is inspired by Hapi with a matching route object API and a rich supporting API.

### Laravel

1. [Drash](https://github.com/drashland/deno-drash) - Drash provides middleware similar to Laravel, but also takes inspiration from Flask and Tonic, as well as introducing it's own concepts.

### Unclassified

The following frameworks didn't feel like they quite fit into another of the above categories:

- [Abc](https://github.com/zhmushan/abc) - Although Abc API supports a context like object, it is somewhat different to the Koa context, and is unlike the other existing Node web frameworks.
- [Fen](https://github.com/fen-land/deno-fen) - Fen also supports a context like object API for it's routing and middleware, but makes use of a router and controller setup which differs somewhat from the listed Node modules.

---

## The ones that got away

As you may have noticed, I have not reviewed 100% of all available frameworks. The ones focused on in this article were chosen based on the following considerations in order to keep the scope reasonable and limit the overhead of having to test, review and write-up everything(!):

- Does the README make it explicit that the project is a work in progress? If so, then don't review.
- Is the framework and abstraction over another framework? If so, then don't review.
- Am I able to easily understand the documentation and get started? If not, then don't review. (This is just my opinion!)

I encourage you to also review the following which based on these (relatively arbitrary!) factors and maybe some others I did not cover this time round:

- [Alosaur](https://github.com/alosaur/alosaur) - A very cool looking Decorator based web framework which appears to be well maintained and popular. One I plan to try out and review in the future.
- [Levo](https://github.com/levo-framework/core/) - A frontend framework that supports Server-Side Rendering (SSR) and The Elm Architecture (TEA) out of the box. This framework is designed for web pages and SPAs, and shouldn't be used for APIs. It offers lots of awesome features out of the box like brotli compression, directory based routing and virtual DOM diffing - definitely one to watch!
- [Dactyl](https://github.com/liamtan28/dactyl) - Dactyl is built on top of the Oak framework, and aims to achieve the same goals as Nest did for Express by providing declarative controllers to the user. Like Alosaur it makes heavy use of Decorators available with Deno's support of TypeScript.
- [MandarineTS](https://github.com/mandarineorg/mandarinets) - MandarineTS is a typescript framework for creating websites using the Model View Controller (MV) pattern. It has several features such as built-in dependency injection, sessions, ORM and a templating engine, and also makes good use of Decorators.
- [Dinja](https://github.com/denjucks/dinja) - Dinja, like Dactyl, is another higher level framework providing APIs over the top of the Pogo framework, and pulling in a templating engine, and various SQL modules.
- [Mith](https://github.com/JWebCoder/mith) - A middleware framework inspired by Express. Where Mith differs from Express is how it solely focusses on providing a robust middleware system, and thus has no support for Routes. It also attempts to leave the Deno `ServerRequest` and `Response` objects as untouched as possible.
- [Jurassic](https://github.com/oknoorap/jurassic) - A path "zero-config", path based routing framework.
- [Arkoren](https://github.com/arkoren/arkoren) - Arkoren says it "aims to be one of the next generation web frameworks available" with features such as "type-safe" and APIs inspired by Laravel. It however is currently in early stages of development and thus is not ready for use.
- [SF](https://github.com/txthinking/sf) - I am truly baffled by this web framework offering. On one hand it makes a point of discussing "how stupid" it is, without really ever explaining it's purpose! It intrigues me because from the limited documentation it appears to support a whole host of features and APIs for dealing with Redis, CRON, making HTTP requests as well as handling and responding to HTTP(S) requests.
- [Deno Express](https://github.com/NMathar/deno-express) - A clone of one of the [original demo servers for Deno](https://github.com/jinjor/deno-playground/tree/master/expressive), despite it's name there is no similarity in it's internals to Express, though it does offer an elegant minimal Express-like API. It's not clear whether it is being actively worked on?
- [MiniServer](https://github.com/pandres95/deno-http-server) - MiniServer is a very minimal server wrapper around the standard Deno library.
- [Centroid](https://github.com/themost-framework/themost) - A work in progress project for implementing the [MOST Web Framework](https://github.com/themost-framework/themost) to Deno.
- [Denosaur](https://github.com/ClementD64/denosaur) - A simple web framework that is currently a work in progress.
- [Espresso](https://github.com/disizali/espresso) - A work in progress minimal web framework that appears to take inspiration from Koa, but with an ambitious roadmap including database integration, graphql and MVC support.
- [Denovel](https://github.com/fauzan121002/denovel) - "A Deno Framework For Web Artisan", Denovel is another web framework drawing inspiration from Laravel. Unlike most frameworks, the author encourages you to clone the repository as a starting point, it doesn't appear to be a module you can import - core packages can be taken from the vendor directory however.
- [DeliGenius](https://github.com/deligenius/deligenius) - A lightweight middleware framework with Koa inspired API and [very impressive performance](https://www.deligenius.com/docs/benchmark) - one to watch.

---

I hope this review was helpful!

If you have been using one of the mentioned web frameworks for Deno, or maybe something I haven't covered(!), I would love to hear what you think about it - please drop your reviews and comments in the section below.

If you are a maintainer of a project and I've missed of your project, or you feel I've mis-represented it then please drop a comment and we can look to add / update the article!

Until next time, thanks for reading! 🦕

---

P.S. Looking for a way to test you HTTP servers? Why not check out [SuperDeno](https://github.com/asos-craigmorten/superdeno) :tada:

![Super Deno standing in the rain at night – stoically facing the dark battle that is software engineering](https://dev-to-uploads.s3.amazonaws.com/i/ow4q11t16oi955bl1byy.png)