Hono vs Express — the Node.js web framework choice in 2026
Hono is faster, ships TypeScript out of the box, and runs on every edge runtime. Express 5 is stable, battle-tested, and has a deeper ecosystem. How to choose.
By toolchew
2,099 words · 11 min read
Start new projects on Hono. The TypeScript story is better by design, the bundle is 17× smaller, and the same code targets any runtime. Pick Express 5 if your team has years of Express patterns embedded, you depend on specific middleware with no Hono equivalent, or you are maintaining a working Express codebase with no edge deployment in sight. Both are actively maintained. The migration cost between them is real.
Who this is for
Developers choosing a server framework for a new project, or evaluating whether an Express codebase is worth migrating. If you are running Fastify or Koa and happy with it, this comparison won’t change your mind.
Versions tested
Hono v4.12.25 (released June 9, 2026) — 30,896 GitHub stars, 99.5% TypeScript codebase, zero external dependencies.
Express v5.2.1 (released December 1, 2025) — 69,142 GitHub stars, the Technical Committee’s endorsed production release, requires Node.js 18+.
Express 4 remains officially supported, but active development has shifted to Express 5. If you are still on Express 4, upgrade to 5; the changes are manageable, and there is no reason to stay on 4.
Why this comparison matters now
Four years ago Hono had roughly 1,000 weekly npm downloads. It was a Cloudflare Workers niche tool. As of June 2026 it sits at approximately 20–35 million weekly downloads — the range reflects measurement differences across aggregators, so check npmtrends for current data. Express still leads at ~93–95 million weekly downloads, but the growth trajectory tells a different story.
The reason for Hono’s climb: its architecture is built on web-standard APIs (the Fetch API). The same code runs unchanged on Node.js, Bun, Deno, Cloudflare Workers, Vercel Edge, and Netlify Edge Functions. Express is built on Node.js-specific primitives — http.IncomingMessage, Buffer, stream — that are absent or poorly emulated on edge runtimes. Getting Express onto Cloudflare Workers requires the nodejs_compat flag, which bloats the bundle well past Workers’ size constraints. For practical purposes, Express cannot run on Workers.
That is the structural shift behind the download curve. Edge and serverless deployment is no longer a niche path — it is the default for new greenfield projects at scale. Hono was built for that world. Express was not.
Head-to-head
| Hono v4.12.25 | Express v5.2.1 | |
|---|---|---|
| Bundle (gzipped) | <14 KB | ~236 KB |
| External dependencies | 0 | Multiple |
| TypeScript | First-class, ships with package | Via @types/express (~57.4M weekly downloads as of June 2026) |
| Built-in middleware | ~23 | 3 |
| Third-party middleware | 62 official @hono packages (as of June 2026) | Thousands |
| Edge runtimes | All major runtimes, natively | Node.js only (compat shims elsewhere) |
| Node.js | Via @hono/node-server adapter | Native |
| Weekly npm downloads | ~20–35M | ~93–95M |
| GitHub stars | 30,896 | 69,142 |
Performance
Hono is faster than Express on Node.js. The gap is not marginal.
Community benchmarks consistently put Hono at approximately 4–5× more requests per second than Express in hello-world scenarios. On Bun the gap widens. The honest caveat: most of these benchmarks do not disclose hardware, tooling versions, or connection concurrency settings. Treat 4–5× as directional. It is consistent enough across independent reports to be a real signal, not a cherry-picked outlier.
What is verifiable from primary sources: Hono’s own benchmark page shows 402,820 ops/sec on Cloudflare Workers versus 297,036 ops/sec for the next fastest Workers-native framework. On Deno (v1.22.0, M1 Pro, Hono v3.0.0), Hono hit 136,112 req/sec against Deno-native alternatives. These are Hono versus other modern frameworks — not Hono versus Express, since Express cannot run in those environments at all.
The bundle size difference matters independently of raw throughput. Hono’s hono/tiny preset stays under 12 KB with zero dependencies. Express gzips to ~236 KB, and the bundle you actually deploy to a Workers environment swells beyond 2 MB with compat shims. On a V8 isolate with a 1 MB size budget, the numbers make the decision before you write a single line of code.
For pure Node.js: the performance gap narrows because Hono uses a @hono/node-server adapter rather than binding directly to Node’s HTTP primitives. The architectural advantage is real but smaller than edge benchmarks imply.
Middleware ecosystem
Hono ships with ~23 built-in middleware packages: CORS, JWT, rate limiting, CSRF protection, compression, caching, request logging, secure headers, basic auth, bearer auth, timeout, and others — all zero external dependencies. A working production middleware stack ships with the package.
Express ships with 3 built-ins: express.static(), express.json(), express.urlencoded(). Everything else is an additional npm install.
That sounds like a Hono win until you look at ecosystem depth. Hono’s official third-party ecosystem currently lists 62 packages under the @hono namespace (as of June 2026) — split across auth adapters (Clerk, Auth.js, Firebase, Stytch), schema validators (Zod, Valibot, ArkType, TypeBox), OpenAPI tooling (Scalar, Swagger UI), monitoring (Sentry, OpenTelemetry, Prometheus), and utilities (session, rate limiter, MCP, tRPC). For the majority of API projects, that coverage is sufficient.
Express’s third-party ecosystem is the entire Node.js middleware world: thousands of packages covering every authentication strategy Passport supports, every ORM integration, every logging stack that has ever been ported to Node.js. If you have a specific, niche middleware requirement, Express almost certainly has a battle-tested package for it. Hono may require writing an adapter or waiting for a community port.
The fundamental incompatibility matters: Express middleware uses (req, res, next) signatures. Hono middleware uses (c, next), where c is a context object wrapping both request and response. You cannot drop an Express middleware into Hono. Each package in your package.json that exposes (req, res, next) is a migration item.
If authentication strategy is a key consideration — choosing between hosted auth (Clerk) and self-hosted auth (Better Auth) — see our Better Auth vs Clerk comparison.
TypeScript DX
Hono is 99.5% TypeScript and ships its own types. The practical difference shows up in three places.
Typed request access. c.req.param('id'), c.req.query('filter'), c.req.header('authorization') — all typed. No casting.
Typed body validation. Pair Hono with a schema validator and the compiler knows the shape of the request body before your handler runs:
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
app.post(
'/users',
zValidator('json', z.object({ name: z.string(), email: z.string().email() })),
(c) => {
const { name, email } = c.req.valid('json') // fully typed
return c.json({ id: '1', name, email })
}
)
Hono RPC. Export the route type from the server and import it in the client. Full end-to-end type inference without code generation:
// server.ts
export type AppType = typeof route
// client.ts
import { hc } from 'hono/client'
import type { AppType } from './server'
const client = hc<AppType>('http://localhost:3000')
const res = await client.users.$post({ json: { name: 'Alice', email: '[email protected]' } })
// res is typed — the compiler knows the response shape
Express with TypeScript looks fine until req.body, which is typed as any. You can add assertions and augmentation interfaces, but the compiler will not catch shape mismatches between what a client sends and what a handler expects. The @types/express package sees ~57.4M weekly downloads (as of the week of 2026-05-27) — roughly matching the express package volume itself — which tells you TypeScript was retrofitted, not designed in. For teams that have debugged req.body: any bugs in production, this is a structural problem, not a minor ergonomic complaint.
Edge and serverless compatibility
Hono runs natively on Cloudflare Workers, Fastly Compute, Deno Deploy, Bun, Vercel Edge, Netlify Edge, AWS Lambda, Lambda@Edge, and Node.js via @hono/node-server. Cloudflare published Hono in its official Workers framework guide. That is as close to a platform endorsement as a framework gets.
Express runs on Node.js natively, on Bun and Deno via compatibility layers, and on AWS Lambda via wrappers. It does not run on Cloudflare Workers in any practical sense — the bundle exceeds size limits before you add your application code. If your deployment target is Cloudflare Workers or any V8 isolate runtime, Hono is not the better option. It is the only reasonable one.
Migrating from Express to Hono
The routing syntax is similar enough that small apps move in a day. The middleware pipeline is where the time goes.
Routing
// Express
app.get('/users/:id', (req, res) => {
res.json({ id: req.params.id });
});
// Hono
app.get('/users/:id', (c) => {
return c.json({ id: c.req.param('id') });
});
Middleware
// Express
app.use((req, res, next) => {
if (!req.headers.authorization) return res.status(401).json({ error: 'Unauthorized' });
next();
});
// Hono
app.use(async (c, next) => {
if (!c.req.header('authorization')) return c.json({ error: 'Unauthorized' }, 401);
await next();
});
Error handling
// Express
app.use((err, req, res, next) => { res.status(500).json({ error: err.message }); });
// Hono
app.onError((err, c) => { return c.json({ error: err.message }, 500); });
Migration complexity by project size:
- Simple CRUD REST API — 1–3 days
- Heavy middleware pipeline (custom auth, logging, rate limiting, session) — 1–2 weeks
- Express-specific package dependencies (Passport strategies, libraries with
(req, res, next)API surface) — 2–4 weeks minimum; longer if you depend on strategies without Hono equivalents
The dependency audit is the first step. Run npm ls --depth=0, then flag every package that exposes an Express-compatible middleware interface. That list is your migration backlog. On Railway or any PaaS hosting a large existing Express app, migration is an engineering investment with a specific payoff only when you need what Hono offers. Know your reason before you start.
When to pick Hono
- New project deploying to Cloudflare Workers, Vercel Edge, or any other V8 isolate runtime
- TypeScript project where you want compile-time guarantees on request and response shapes
- Bundle size is a constraint — Workers size limits, cold-start latency on serverless, Lambda cold starts
- You want a working middleware stack without wiring up external packages
- New Node.js project with no legacy dependencies
When to pick Express
- Existing Express codebase — the migration cost rarely justifies the switch unless you have a concrete need for edge deployment or a persistent TypeScript problem
- Project depends on packages tied to the
(req, res, next)API with no Hono equivalent yet - Team has deep Express familiarity and a large body of internal tooling built around Express conventions
- Pure Node.js PaaS deployment where edge runtime benefits are irrelevant
Verdict
Use Hono for new projects. The TypeScript experience is better by construction, not by convention. The bundle is small enough to run anywhere. The middleware API is clean. The RPC layer removes an entire class of client-server type bugs. Express had a 15-year head start and it shows in ecosystem depth — but depth only matters when you need something Hono’s 62 official packages (as of June 2026) don’t cover.
Migrate an existing Express app only when you have a specific problem Hono solves: an edge deployment target you cannot reach, TypeScript pain that costs you debugging time regularly, or a dependency you are actively trying to eliminate. “Hono is newer” is not a migration reason. A working Express app is worth money; rewriting it for its own sake is not.
For developers still uncertain: write one route handler in Hono’s API. Write one middleware. It is readable in 20 minutes. If it does not click, Express 5 is a quality release and will be supported well past 2026.
If you have committed to Hono and are building out the rest of the stack, our TypeScript ORM comparison covers the data layer and our full-stack deploy platform roundup covers where to run it.
Caveats
The 4–5× Node.js throughput advantage comes from community benchmarks without disclosed hardware or methodology. The direction is consistent across sources; the exact multiplier is not independently verifiable from primary sources. TechEmpower Round 23 rankings for JavaScript frameworks were not extracted for this article — see techempower.com/benchmarks for current numbers. Cold-start latency in milliseconds is cited in secondary sources only; no primary-source benchmark with disclosed methodology was found. This article contains affiliate links.
References
- Hono GitHub — version, stars, security changelog
- Express GitHub — v5.2.1 release date, stars
- expressjs.com support lifecycle — Express 5 as latest release, Express 4 ongoing supported release
- hono.dev benchmarks — Cloudflare Workers and Deno numbers (primary source)
- npmtrends: hono vs express — download comparison chart
- Hono third-party middleware — 62 @hono packages (as of June 2026)
- Hono RPC docs — type-safe client pattern
- Cloudflare Workers Hono guide — official platform endorsement
- @types/express on socket.dev — ~57.4M weekly downloads (as of week of 2026-05-27)