Node.js has been the dominant server-side JavaScript runtime for over a decade, and the ecosystem of HTTP frameworks has evolved dramatically. What started with Express’s minimalist callback chains has grown into a landscape of async-native, TypeScript-first frameworks optimized for specific use cases — from edge computing to enterprise microservices.

This comparison evaluates four major Node.js HTTP frameworks: Express (69,262 ⭐), Koa (35,701 ⭐), Fastify (36,841 ⭐), and Hono (31,492 ⭐). Each represents a distinct philosophy about how HTTP servers should be built.

Comparison Table

FeatureExpressKoaFastifyHono
GitHub Stars69,26235,70136,84131,492
Async ModelCallback-basedasync/await nativeasync/await nativeasync/await native
MiddlewareLinear chainCascading (onion)Plugin systemMiddleware chain
Schema ValidationNone (manual)None (manual)Built-in (JSON Schema)Built-in (Zod)
TypeScript@types/expressBuilt-inBuilt-inBuilt-in
Bundle Size~2MB (deps)~600KB~1.5MB~50KB (min)
Request/sec~25K~40K~65K~140K (Bun)
Edge RuntimeLimitedLimitedPartialNative
Last UpdatedJul 2026Jul 2026Jul 2026Jul 2026

Express: The Battle-Tested Workhorse

Express is the most deployed Node.js framework in history — with nearly 70,000 GitHub stars and millions of production deployments. Its minimalist design (a thin layer over Node’s http module with middleware support) has spawned an ecosystem of thousands of middleware packages.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const express = require('express');
const app = express();

app.use(express.json());

app.get('/api/users/:id', async (req, res) => {
  try {
    const user = await db.findUser(req.params.id);
    if (!user) return res.status(404).json({ error: 'Not found' });
    res.json(user);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.listen(3000, () => console.log('Express on :3000'));

Express’s greatest strength — its massive ecosystem — is also its greatest liability in 2026. The framework was designed in the callback era, and while middleware has evolved to support Promises, the underlying architecture remains synchronous at heart. Error handling requires manual try/catch wrapping in every route handler, and request validation is entirely manual.

That said, Express remains the best choice for teams that need maximum compatibility with existing middleware packages (Helmet, CORS, Morgan, compression) and don’t require bleeding-edge performance. For new projects, however, the three frameworks below offer compelling improvements.

Koa: The Async-Native Evolution

Koa was created by the same team behind Express, designed from the ground up for async/await. It replaces Express’s linear middleware chain with a cascading (onion) model where middleware can both intercept requests before passing to downstream handlers and modify responses after they come back.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const Koa = require('koa');
const app = new Koa();

// Onion middleware: runs BEFORE downstream AND AFTER
app.use(async (ctx, next) => {
  const start = Date.now();
  await next();  // pass control downstream
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
});

app.use(async (ctx) => {
  ctx.body = { message: 'Hello from Koa' };
});

app.listen(3000);

The onion model is Koa’s killer feature. It enables clean patterns for logging, timing, authentication, and response transformation without nested callbacks. However, Koa deliberately ships with almost nothing built-in — no router, no body parser, no static file serving. You assemble your stack from community middleware (koa-router, koa-body, koa-static), which means more upfront decisions but a leaner final bundle.

Koa is ideal for teams that want Express-like simplicity with modern async patterns. Its performance is ~60% better than Express for typical workloads due to reduced callback overhead.

Fastify: Performance-First with Schema-Driven Development

Fastify takes a radically different approach: every route must declare an input and output JSON Schema. This isn’t just for validation — Fastify uses schema definitions to serialize responses 2-3x faster than JSON.stringify() through its custom fast-json-stringify compiler.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const fastify = require('fastify')({ logger: true });

fastify.get('/api/users/:id', {
  schema: {
    params: {
      type: 'object',
      properties: { id: { type: 'string', pattern: '^[a-f0-9]{24}$' } },
      required: ['id']
    },
    response: {
      200: {
        type: 'object',
        properties: {
          id: { type: 'string' },
          name: { type: 'string' },
          email: { type: 'string', format: 'email' }
        }
      }
    }
  }
}, async (request, reply) => {
  const user = await db.findUser(request.params.id);
  return user;  // automatically serialized via fast-json-stringify
});

await fastify.listen({ port: 3000 });

The schema-first approach generates automatic Swagger/OpenAPI documentation via @fastify/swagger — every route you define becomes a documented endpoint with no additional effort. Fastify also has an extensive plugin system with official plugins for rate limiting, CORS, JWT authentication, WebSockets, and more.

For REST APIs with structured request/response contracts, Fastify offers the best developer experience. Its performance (~65K req/s) is more than sufficient for most applications, though Hono pushes even further.

Hono: Edge-Native and Ultralight

Hono (Japanese for “flame”) is the newest entrant, designed explicitly for edge runtimes — Cloudflare Workers, Deno, Bun, and AWS Lambda. At just ~50KB, it’s the smallest of the four while delivering the highest throughput (~140K req/s on Bun) thanks to its zero-overhead design.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { Hono } from 'hono';
import { z } from 'zod';
import { zValidator } from '@hono/zod-validator';

const app = new Hono();

const userSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
});

app.post('/api/users', zValidator('json', userSchema), async (c) => {
  const data = c.req.valid('json');
  // data is fully typed: { name: string; email: string }
  return c.json({ id: 'abc123', ...data }, 201);
});

export default app;  // deploy directly to Cloudflare Workers

Hono’s built-in Zod integration provides compile-time type inference — meaning TypeScript knows the exact shape of validated request bodies, query parameters, and headers without manual type annotations. It also supports JSX for server-side rendering, making it suitable for full-stack applications deployed at the edge.

Where Hono falls short: it intentionally lacks the plugin ecosystems of Express and Fastify. For traditional long-running Node.js servers with database connections, connection pools, and background job processing, Express or Fastify are more practical. Hono shines when your deployment target is a serverless function or edge runtime where cold starts and bundle size matter.

Setting Up a Production Express Alternative

If you’re migrating from Express to Fastify, here’s a Docker Compose setup that runs a Fastify API behind Caddy for automatic HTTPS:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# docker-compose.yml
version: '3.8'
services:
  api:
    image: node:22-alpine
    working_dir: /app
    volumes:
      - ./:/app
    command: node server.js
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://user:pass@db:5432/app
    ports:
      - "3000:3000"
    depends_on:
      - db
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
  caddy:
    image: caddy:2-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data

volumes:
  pgdata:
  caddy_data:

Choosing the Right Framework

  • Express: Best for legacy projects, maximum middleware compatibility, and teams that prioritize ecosystem over performance.
  • Koa: Best for teams that want async-native middleware with Express-like simplicity and don’t mind assembling their own stack.
  • Fastify: Best for REST APIs that benefit from automatic OpenAPI docs, schema-driven validation, and strong TypeScript support.
  • Hono: Best for edge deployments (Cloudflare Workers, Deno, Bun) where bundle size and cold-start performance are critical.

For related reading, see our TypeScript HTTP client libraries comparison and GraphQL server libraries guide. For deployment strategies, check our reverse proxy comparison guide.

Why Your Framework Choice Shapes Infrastructure Decisions

The HTTP framework you choose influences more than just code style — it affects deployment architecture, observability, and scaling strategy. Express and Fastify are designed for long-lived server processes with connection pools and in-memory caches, which align well with traditional VM-based deployments. Hono’s edge-native design pushes you toward serverless architectures where each request is isolated — better for bursty workloads but requiring stateless design patterns. Understanding these implications before selecting a framework prevents costly re-architecting six months into a project.

FAQ

Can I migrate from Express to Fastify incrementally?

Yes, but it requires planning. Fastify has an @fastify/express plugin that wraps Express middleware as Fastify plugins, allowing you to run both frameworks in the same process. Start by creating new endpoints in Fastify, then gradually migrate old Express routes over several sprints.

Is Koa still maintained?

Yes. The Koa team (which includes TJ Holowaychuk, Express’s original creator) continues to release updates. The most recent release was in 2025. While the ecosystem is smaller than Express’s, Koa’s minimalist API means there’s less surface area that needs maintenance.

How does Hono compare to Express in production at scale?

Hono matches or exceeds Express throughput in benchmarks, but production readiness depends on your deployment model. For serverless/edge deployments, Hono is production-proven at companies like Cloudflare. For long-running Node.js servers, Express and Fastify have more battle-tested middleware for connection pooling, graceful shutdown, and cluster mode.

Does Fastify’s JSON Schema validation impact performance?

No — it improves it. Fastify compiles JSON Schema validators at startup time using ajv, and serializes responses using fast-json-stringify (which generates a JavaScript function specialized to your schema). This is faster than the generic JSON.stringify() that Express uses.

Can Hono run on a regular Node.js server?

Yes. Hono has a @hono/node-server adapter that runs Hono apps on Node’s http.createServer. You get Hono’s API and middleware on Node.js without changing your deployment infrastructure. Performance is comparable to Fastify for most workloads.

What’s the most important factor when choosing between these frameworks?

Ecosystem maturity for your specific use case. If you need rate limiting, CORS, cookie parsing, and static file serving, Express has battle-tested packages for all of them. If you’re building a new REST API from scratch with TypeScript, Fastify’s integrated approach (schema → validation → serialization → docs) will save you weeks of integration work.


💰 想测试你的市场判断力?我用 Polymarket 做预测市场交易——这是全球最大的预测市场平台,从大选结果到技术监管时间线,什么都可以押注。和赌博不同,这是真正的信息市场:你懂的信息越多,胜率越高。我靠预测技术相关事件的走向已经赚了不少。用我的邀请链接注册:Polymarket.com