Skip to main content

Hono vs Express vs Fastify 2026

·PkgPulse Team

Express.js turned 13 in 2023. It's still the most-downloaded Node.js web framework by a wide margin — ~35 million weekly downloads — running on servers that have never been updated and powering backend APIs that nobody wants to touch. Fastify emerged as the performance-focused alternative, shipping JSON schema validation and 2-3x faster throughput than Express. Then Hono arrived with a different premise entirely: a web framework that runs anywhere the Fetch API runs — Node.js, Bun, Deno, Cloudflare Workers, Vercel Edge, AWS Lambda.

In 2026, the question isn't "which is fastest." It's "which runtime do you need to target?"

TL;DR

New Node.js API: Use Fastify — schema validation, serialization, plugin lifecycle, and 2-3x faster than Express. Edge/multi-runtime: Use Hono — runs on Cloudflare Workers, Bun, Deno, and Node.js from a single codebase. Existing Express codebase: Express is fine; migrate to Fastify when performance becomes a bottleneck. Don't rewrite working code without a reason.

Key Takeaways

  • Express: ~35M weekly downloads — still dominant by volume, but essentially in maintenance mode
  • Fastify: ~4M weekly downloads, ~33K stars — the performance-first Node.js framework
  • Hono: ~3M weekly downloads, ~22K stars — fastest growth, edge-native, WinterCG-compliant
  • Throughput: Hono ≈ Fastify (120-150K RPS) >> Express (~40K RPS) on hello-world benchmarks
  • Real-world difference narrows with database queries and business logic — all frameworks converge around 10-15K RPS with a real DB call
  • TypeScript DX: Hono and Fastify have excellent TS support; Express types are an afterthought

At a Glance

Express 5Fastify 5Hono 4
Version5.05.04.x
GitHub stars~65K~33K~22K
Weekly downloads~35M~4M~3M
Hello-world RPS~40K~120-150K~120-160K
TypeScriptCommunity typesBuilt-inBuilt-in, excellent
Schema validationManualJSON SchemaZod/Valibot adapters
Edge runtime
Bundle size~200KB~300KB~14KB
Middleware ecosystemMassive (1000+)LargeGrowing fast
Learning curveMinimalMediumLow-Medium
Best forLegacy, simple APIsHigh-perf Node.js APIsEdge, multi-runtime, new projects

Express: The Default That Refuses to Die

Express is the jQuery of Node.js web frameworks. Almost every tutorial, bootcamp, and "build a REST API" blog post uses Express. The ecosystem is enormous. If something needs to be done in Express, there's a package for it.

import express from 'express'

const app = express()
app.use(express.json())

app.get('/users/:id', async (req, res) => {
  const user = await db.users.findById(req.params.id)
  if (!user) return res.status(404).json({ error: 'Not found' })
  res.json(user)
})

app.post('/users', async (req, res) => {
  const { name, email } = req.body
  // No built-in validation — you add your own
  const user = await db.users.create({ name, email })
  res.status(201).json(user)
})

app.listen(3000)

Express 5 (released 2024): After years of waiting, Express 5 brings native async/await error handling (no more try/catch wrapping for async middleware), dropped support for some legacy patterns, and minor performance improvements. The API is intentionally backward-compatible.

The problems with Express in 2026:

  • No built-in schema validation — adds latency and bugs
  • Slow JSON serialization (uses JSON.stringify without fast-path optimization)
  • No TypeScript-native types — @types/express is community-maintained
  • No built-in request/response lifecycle hooks
  • Not compatible with edge runtimes (uses Node.js-specific APIs)

When Express is still correct: You have existing middleware that doesn't exist for other frameworks (complex auth flows, legacy payment processing libraries, decades-old session management code). You're a solo developer building an internal tool and the performance headroom is irrelevant. Your team knows Express and onboarding overhead isn't worth the switch.


Fastify: The Right Default for Node.js APIs

Fastify was built with two constraints Express ignores: performance and validation. It ships JSON Schema validation as a first-class feature — define the shape of your request and response, and Fastify validates incoming data and serializes outgoing data using fast-json-stringify, which is 2-3x faster than JSON.stringify.

import Fastify from 'fastify'

const fastify = Fastify({ logger: true })

// Schema-first approach — validation + serialization in one
const userSchema = {
  body: {
    type: 'object',
    required: ['name', 'email'],
    properties: {
      name: { type: 'string', minLength: 1 },
      email: { type: 'string', format: 'email' },
    },
    additionalProperties: false,
  },
  response: {
    201: {
      type: 'object',
      properties: {
        id: { type: 'string' },
        name: { type: 'string' },
        email: { type: 'string' },
      },
    },
  },
}

fastify.post('/users', { schema: userSchema }, async (request, reply) => {
  // request.body is validated and typed
  const user = await db.users.create(request.body)
  return reply.code(201).send(user)
})

await fastify.listen({ port: 3000 })

Fastify's plugin lifecycle is one of its strongest features. Plugins can declare dependencies, encapsulate routes, and share decorators — it solves the code organization problem that Express leaves entirely to the developer:

// Fastify plugin encapsulation
fastify.register(async function authRoutes(fastify) {
  fastify.addHook('preHandler', authenticate)

  fastify.get('/profile', async (request) => {
    return request.user  // injected by authenticate hook
  })
}, { prefix: '/api' })

Fastify 5 (2024): Node.js 20+ required, TypeScript ESM support improved, new type providers for Zod and TypeBox alongside the existing JSON Schema system.

Limitation: Fastify is Node.js only. No Cloudflare Workers, no Bun-native, no Deno Deploy. If you need multi-runtime deployment, look at Hono.


Hono: Edge-Native, Anywhere the Fetch API Runs

Hono's design constraint is radical: implement against the WinterCG Fetch API standard only. No process, no fs, no Node.js built-ins. The result is a framework that runs identically on Node.js, Bun, Deno, Cloudflare Workers, Vercel Edge Functions, Netlify Edge, and AWS Lambda@Edge — often with the same config file.

import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'

const app = new Hono()

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

app.post('/users',
  zValidator('json', createUserSchema),
  async (c) => {
    const data = c.req.valid('json')  // Fully typed
    const user = await db.users.create(data)
    return c.json(user, 201)
  }
)

// Deploy anywhere — same code:
export default app  // Cloudflare Workers
// or: serve(app)   // Bun
// or: serve(app)   // Deno
// or: const handler = handle(app)  // AWS Lambda

Hono RPC is a unique feature — generate a type-safe client from your route definitions with zero code generation:

// server.ts — define routes with return types
const routes = app
  .get('/users/:id', async (c) => {
    const user = await getUser(c.req.param('id'))
    return c.json(user)  // TypeScript infers the return type
  })

export type AppType = typeof routes

// client.ts — fully typed client, no schema definition needed
import { hc } from 'hono/client'

const client = hc<AppType>('https://api.example.com')
const user = await client.users[':id'].$get({ param: { id: '123' } })
// user is fully typed — same shape as the server response

Bundle size: Hono is ~14KB — orders of magnitude smaller than Express (~200KB) or Fastify (~300KB). On cold-start-sensitive environments like Cloudflare Workers or Lambda, this directly reduces latency.

The ecosystem gap: Hono's middleware library is growing but smaller than Express or Fastify. Complex auth flows, specialized database adapters, and enterprise middleware are better covered by the established frameworks. For new greenfield projects, the gap is increasingly irrelevant — @hono/auth-js, @hono/jwt, @hono/zod-validator cover most common needs.


Performance in Context

Hello world JSON endpoint (requests/second, single core):

Framework         Node.js   Bun      Cloudflare Workers
Express 5:        ~40K      ~60K     ❌ (not supported)
Fastify 5:        ~130K     ~160K    ❌ (not supported)
Hono 4:           ~120K     ~180K    ~1.2M (V8 isolate)

Real-world API (DB query + JSON response, PostgreSQL, same machine):
Express:  ~10K RPS
Fastify:  ~13K RPS
Hono:     ~12K RPS

At real-world scale, all three converge. The hello-world benchmarks
measure JSON serialization overhead, not application performance.

The performance gap narrows dramatically once you add a database call. Choosing Fastify over Express for a 30% throughput gain on a DB-bound API is rarely worth the migration cost. The real reasons to switch:

  • Fastify over Express: Built-in validation catches bugs before they ship, schema-based serialization reduces response payload size, plugin lifecycle organizes large codebases
  • Hono over either: You need the same code to run on Node.js, Cloudflare Workers, and Bun — or you're building an edge-first architecture

When to Use Each

Express → Legacy Node.js API that works, massive existing middleware needs, team deeply familiar with the ecosystem, internal tools where performance isn't measured.

Fastify → New Node.js service that stays on Node.js, high-throughput APIs where the 2-3x performance matters, applications where request validation is critical (prevents entire classes of bugs), large codebases that benefit from the plugin lifecycle.

Hono → New projects targeting edge deployment, multi-runtime support required (same code runs on Node.js, Workers, Bun, Deno), lightweight APIs with cold-start sensitivity, projects that want Zod-based type safety throughout the request/response cycle, or teams building with Bun as the primary runtime.


Compare Hono, Express, and Fastify package health on PkgPulse.

Related: Hono vs Elysia 2026 · Hono RPC vs tRPC vs ts-rest · Express vs Fastify 2026

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.