tinyhttp vs. Express.js: Comparing Node.js frameworks
Published: 2021-06-23 19:40:28

**Written by [Shubham Kumar](https://blog.logrocket.com/author/shubhamkumar/)** ✏️

In this guide, we’ll compare one of the most commonly used frameworks for building web applications with Node.js, Express.js, with tinyhttp, one of its most popular alternatives.

Here’s what we’ll cover:

*   [What is tinyhttp?](#what-is-tinyhttp)
*   [What is Express.js?](#what-is-expressjs)
*   [tinyhttp vs. Express.js: A basic comparison](#tinyhttp-vs-expressjs-a-basic-comparison)
*   [Performance benchmark](#performance-benchmark)
*   [tinyhttp and Express.js in action: A simple example](#tinyhttp-and-expressjs-in-action-a-simple-example)

## What is tinyhttp?

[tinyhttp](https://github.com/talentlessguy/tinyhttp) is a modern web framework similar to Express.js that is written in TypeScript. It uses a very minimal amount of dependencies compared to Express.js, which makes it super fast.

tinyhttp delivers routing, req/res extensions, and much more, all while depending on only six modules — four of which are tinyhttp’s own.

All the middleware that was created for Express.js works smoothly with tinyhttp. Check out this [tinyhttp + Express/GraphQL](https://github.com/talentlessguy/tinyhttp/tree/master/examples/graphql) integration for an example of how to use Express.js middleware with tinyhttp.

tinyhttp also supports async/await for routes, which is not the case in Express.js. There are proper typings and a function checker inside tinyhttp, which resolves async functions. In other words, both sync and async work fine in tinyhttp. Check out these [async](https://github.com/talentlessguy/tinyhttp/tree/master/examples/async) and [MongoDB](https://github.com/talentlessguy/tinyhttp/tree/master/examples/mongodb) examples to see how to make async handlers.

Here is a short list of the most important features of tinyhttp, according to the [official docs](https://github.com/talentlessguy/tinyhttp#tinyhttp):

*   2.5x faster than Express
*   Full Express middleware support
*   Async middleware support
*   Native ESM and CommonJS support
*   No legacy dependencies, just the JavaScript itself
*   Types out of the box
*   No built-in middleware support

## What is Express.js?

[Express.js](https://expressjs.com/) is a flexible Node.js framework that provides a robust set of features for web and mobile applications. Creating robust APIs is very easy because Express.js comes with lots of middleware and other in-built support.

Express.js doesn’t come with a database; this is left up to third-party modules, which allows you to interface with nearly any database. Express.js supports myriad [template engines](https://expressjs.com/en/guide/using-template-engines.html) that go with the `(path, locals, callback)` signature.

This framework is built in such a way that it acts as a minimal and flexible Node.js web application framework, providing a robust set of features for building single, multipage, and hybrid web applications.

Some features of Express.js:

*   Open source community support
*   Fast app development
*   Easy to learn
*   Template engine support
*   I/O handling
*   Built-in middleware support

## tinyhttp vs. Express.js: A basic comparison

For a high-level comparison of tinyhttp and Express v4, let’s look at the minimum Node.js version supported, ECMAScript version, test coverage, etc.:

| **Criteria** | **tinyhttp** | **express v4** |
| ------------------------------------ | ------------ | -------------- |
| Minimum supported Node.js version | 12.4.0 | 0.10.0 |
| Minimum supported ECMAScript version | ES2019 | ES5 (?) |
| `req` / `res` extensions | ✔️ | ✔️ |
| Test coverage | 92% | 100% |
|Compiled to native ESM | ✔️ | ✖️ |
| TypeScript support | ✔️ | ✖️ |
| Package size (core only) | 35.2 kB | 208 kB |
| Built-in middleware | ✖️ | ✔️ |

Some notes on the table above:

*   The minimum Node.js version that is required for tinyhttp to work is 12.4.0, whereas with Express v4, we can start working with even Node.js 0.10.0
*   The minimum supported version for tinyhttp is ES2019 (ES10), whereas in Express v4, we need ES5
*   `req` is an object containing information about the HTTP request that raised the event. In response to `req`, you use `res` to send back the desired HTTP response. Both tinyhttp and express v4 support `req`/`res` extensions
*   Test coverage for the codebase is 92 percent for tinyhttp and 100 percent for Express.js v4
*   The ESM (EcmaScript Modules) specification introduced with the ES6 (or ES2015) norm describes how to import and export modules in JavaScript. We can natively use ESM with tinyhttp ,but we need external support, such as [Babel](https://blog.logrocket.com/why-you-dont-need-babel/), for Express.js
*   Unlike Express.js, tinyhttp comes with TypeScript support
*   The core package size of tinyhttp is 35.2kB, compared to 208kB for Express.js
*   tinyhttp doesn’t come with built-in middleware. Express.js does have [built-in middleware](http://expressjs.com/en/guide/using-middleware.html#middleware.built-in)

## Performance benchmark

With the basics out of the way, let’s look at a performance report using the [fastify benchmarking tool](https://github.com/talentlessguy/benchmarks). Here we use parameters as req/s, transfer/s, and latency to measure the performance of both frameworks.

Below are some notes on the hardware, system, and conditions used for this benchmark.

*   **Hardware**:
    *   Xiaomi Pro 2019 Edition (Laptop)
    *   CPU: Intel Core i7-8550U
    *   RAM: 16GB
*   **System:**
    *   kernel: 5.7.19-2
    *   node: 15.5
*   **Conditions**:
    *   100 connections
    *   10 pipelines
    *   40s duration

| **Framework** | **req/s** | **transfer/sec** | **latency** |
| ------------------------ | --------- | ---------------- | ----------- |
| @tinyhttp/app (w/o exts) | 24575 | 3.81 MB | 3.37 ms |
| @tinyhttp/app (esm) | 22820 | 3.54 MB | 4.04 ms |
| @tinyhttp/app (cjs) | 22637 | 3.51 MB | 4.08 ms |
| Express 4.17.1 | 12986 | 2 MB | 7.11 ms |

`req/s` is number of requests per second. `Latency` refers to the delay between a user's action and a web application's response to that action, also referred to as total round-trip time.

From the table above, we can see that tinyhttp is capable of making more transfers per second with lower latency than Express.js v4 

**Note**: Benchmarks aren't completely accurate and may be different on every run and on every machine. The key is to compare proportions instead of absolute values.

To conclude our performance benchmark, tinyhttp (without extra `req`/`res` extensions) is ~1.9 times faster than Express.js.

## tinyhttp and Express.js in action: A simple example

Now it’s time to build a simple example app so we can see tinyhttp and Express.js in action side by side.

You can use any package manager to install tinyhttp and Express. I will use [npm](https://www.npmjs.com/) for demonstration.

To install tinyhttp:

```shell
npm i @tinyhttp/app
```

To install Express.js:

```shell
npm install express
```

### ‘Hello World’

Express.js and tinyhttp app are structured quite similarly. If you know Express.js, then you also know tinyhttp.

tinyhttp:

```javascript
import { App } from '@tinyhttp/app'
const app = new App()
const PORT = 3000

app
  .get('/', (_, res) => void res.send('<h1>Hello World</h1>'))
  .listen(PORT, () => console.log(`Started on http://localhost:${PORT}!`))
```

Express.js:

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

app.get('/', (req, res) => {
  res.send('Hello world');
});

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

You probably noticed that instead of `require`, we used ESM imports. tinyhttp is designed to be used with [Native ESM](https://nodejs.org/api/esm.html). Unlike Express, tinyhttp is compiled to both ESM and CommonJS module systems. Meanwhile, somehow, it’s still much smaller than Express.js.

You can use `import`/`export` syntax in Node.js with it. To set up a Node ESM package, put `"type": "module"` in the `package.json` file, like this:

```javascript
{
  "type": "module"
}
```

Another option is to use an `.mjs` extension. That way, you don't need to put that `"type"` field in `package.json`. For more information, check out the [ECMAScript Modules Node.js documentation](https://nodejs.org/api/esm.html).

Because the most popular Express.js middleware also uses outdated modules, tinyhttp provides a set of its rewrites/remakes of popular wares, such as `logger`, `session`, and so on.

### Routing

Now let’s walk through how to handle some basic routing in both tinyhttp and Express.js. Express.js contains a lot of helper functions in their `req` and `res` objects. tinyhttp fully implements Express.js APIs using methods such as `res.send`, `res.download`, `res.redirect`, and so on.

tinyhttp:

```javascript
import { App } from '@tinyhttp/app'
import { once } from 'events'

const app = new App()
const PORT = 3000

app.get('/', (req, res) => {
    res.send('Sent a GET!')
})

app.post('/', async (req, res) => {
    // Nothing complex here, we just listen to 'data' event and return the data as a promise to a `data` variable
    const data = await once(req, 'data').then(d => d.toString())

    // And then we send it
    res.end(`Sent some data: ${data}`)
})

app.listen(PORT, () => console.log(`Started on http://localhost:${PORT}!`))
```

Express.js

```javascript
var express = require('express');
var app = express();

app.get('/', function(req, res){
   res.send("Send a GET!");
});

app.post('/', function(req, res){
   res.send("hello'!\n");
});

app.listen(3000);
```

## Conclusion

tinyhttp is fast and light, and you can start using it today for backend applications. The [tinyhttp repository](https://github.com/talentlessguy/tinyhttp) contains a lot of [examples](https://github.com/talentlessguy/tinyhttp/tree/master/examples), including [MongoDB](https://github.com/talentlessguy/tinyhttp/tree/master/examples/mongodb) and [GraphQL](https://github.com/talentlessguy/tinyhttp/tree/master/examples/graphql) integrations. I would recommend using tinyhttp when you need to quickly get started with bare-minimum code.

That said, Express.js is still popular and will continue to be used in major projects and industries because of its wide open source community support and easy learning curve.

---

## 200’s only ✔️ Monitor failed and slow network requests in production

Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third party services are successful, [try LogRocket] (https://logrocket.com/signup/).
[![LogRocket Network Request](https://blog.logrocket.com/wp-content/uploads/2019/12/network-request-filter-2-1.png)]
(https://logrocket.com/signup/)

[LogRocket] (https://logrocket.com/signup/) is like a DVR for web apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. [Start monitoring for free] (https://logrocket.com/signup/).