Hono vs itty-router vs worktop 2026
Hono benchmarks at 402,820 requests/second on Cloudflare Workers. itty-router hits 212,598 ops/sec. worktop reaches 197,345 ops/sec. In practice, all three are so fast that routing overhead is essentially zero — the differences that actually matter are bundle size, TypeScript support, middleware ecosystem, and multi-runtime support. itty-router is 1/4 the size of Hono's smallest bundle. Hono is used by Cloudflare internally for D1, Workers Logs, and customer APIs.
TL;DR
Hono for the vast majority of edge projects — 2M weekly downloads, 9+ runtime support, excellent TypeScript, built-in middleware, and a growing ecosystem. itty-router when bundle size is a hard constraint and you need the absolute minimal footprint for a Cloudflare Worker. worktop for TypeScript-first Workers with a clean, typed API and built-in support for CORS, sessions, and route groups. For new projects, Hono is the default choice.
Key Takeaways
- Hono: 2M weekly downloads, 23K GitHub stars, <14kB, runs on 9+ runtimes
- itty-router: 300K weekly downloads, 2.5K stars, AutoRouter is just 1/4 of Hono's smallest bundle
- worktop: 30K weekly downloads, TypeScript-first, Workers-specific features (sessions, CORS)
- Hono benchmarks: 402,820 req/s — fastest routing algorithm (RegExpRouter with Trie)
- itty-router: Chain-based API, additional args propagate to all handlers automatically
- All three: Zero cold starts (Workers isolate model), Web Standards (Fetch API)
- Cloudflare uses Hono internally: D1 Studio, Workers dashboard, customer-facing APIs
The Context: Edge Routing
On Cloudflare Workers, every request handler starts with:
// The Worker entry point (Web Standards)
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Route the request
// Return a Response
}
};
Routers simplify this pattern — matching URLs, extracting params, applying middleware — without adding meaningful overhead at the edge.
Hono
Package: hono
Weekly downloads: 2M
GitHub stars: 23K
Creator: Yusuke Wada
Bundle: <14 kB (smallest preset)
Hono is the most capable edge framework. It's essentially the Express for edge runtimes — familiar API, excellent TypeScript, and support for every modern JavaScript runtime.
Installation
npm install hono
npx create-hono@latest my-app # Scaffold a new project
Basic Usage
import { Hono } from 'hono';
const app = new Hono<{ Bindings: Env }>();
// Route params
app.get('/users/:id', async (c) => {
const id = c.req.param('id');
const user = await c.env.DB
.prepare('SELECT * FROM users WHERE id = ?')
.bind(id)
.first();
return user ? c.json(user) : c.json({ error: 'Not found' }, 404);
});
// Middleware
app.use('*', async (c, next) => {
const start = Date.now();
await next();
c.header('X-Response-Time', `${Date.now() - start}ms`);
});
export default app;
Built-in Middleware
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
import { bearerAuth } from 'hono/bearer-auth';
import { rateLimiter } from 'hono/rate-limiter';
import { compress } from 'hono/compress';
const app = new Hono();
app.use('*', cors({
origin: ['https://app.example.com'],
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
}));
app.use('*', logger());
app.use('/api/admin/*', bearerAuth({ token: Bun.env.API_TOKEN }));
Type-Safe Route Groups
// user.routes.ts
import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
const userSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
});
export const userRoutes = new Hono<{ Bindings: Env }>()
.get('/', async (c) => {
const users = await c.env.DB.prepare('SELECT * FROM users').all();
return c.json(users.results);
})
.post('/', zValidator('json', userSchema), async (c) => {
const data = c.req.valid('json');
const { meta } = await c.env.DB
.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
.bind(data.name, data.email)
.run();
return c.json({ id: meta.last_row_id }, 201);
})
.get('/:id', async (c) => {
const user = await c.env.DB
.prepare('SELECT * FROM users WHERE id = ?')
.bind(c.req.param('id'))
.first();
return user ? c.json(user) : c.json({ error: 'Not found' }, 404);
});
// index.ts
const app = new Hono<{ Bindings: Env }>()
.route('/users', userRoutes)
.route('/products', productRoutes);
export type AppType = typeof app; // For Hono RPC client
export default app;
Hono RPC Client
// Client (React, Node.js, anywhere)
import { hc } from 'hono/client';
import type { AppType } from './worker/index';
const client = hc<AppType>('https://my-api.example.com');
// Fully typed — TypeScript knows all routes, params, and response types:
const response = await client.users.$get();
const users = await response.json(); // typed: User[]
const newUser = await client.users.$post({
json: { name: 'Alice', email: 'alice@example.com' }
});
Multi-Runtime
// The same app.ts runs on all these:
// Cloudflare Workers: export default app
// Deno: Deno.serve(app.fetch)
// Bun: Bun.serve({ fetch: app.fetch })
// Node.js: serve(app) // @hono/node-server
// Vercel Edge: export const GET = handle(app)
// AWS Lambda: export const handler = handle(app)
itty-router
Package: itty-router
Weekly downloads: 300K
GitHub stars: 2.5K
Creator: Kevin R. Whitley
itty-router is extreme minimalism. AutoRouter — its batteries-included variant — is 1/4 the size of Hono's smallest bundle. For simple Workers where bundle size matters (cold start or edge network), itty-router delivers.
Installation
npm install itty-router
AutoRouter (Batteries-Included)
import { AutoRouter } from 'itty-router';
const router = AutoRouter();
router
.get('/users', () => [{ id: 1, name: 'Alice' }]) // Auto-serializes to JSON
.get('/users/:id', ({ id }) => ({ id, name: 'Alice' }))
.post('/users', async (request) => {
const body = await request.json();
return { id: Math.random(), ...body };
});
export default router; // Works as a Workers export directly
itty-router's Unique Feature: Auto-Propagating Args
import { Router } from 'itty-router';
const router = Router();
// Additional args (env, ctx) are automatically propagated to all handlers:
router.get('/users', (request, env, ctx) => {
// env and ctx available without manual wiring
return env.DB.prepare('SELECT * FROM users').all();
});
router.all('*', () => new Response('Not found', { status: 404 }));
export default {
fetch: (...args) => router.fetch(...args),
};
No middleware configuration needed — env and ctx flow through automatically.
itty-router Size Advantage
# Bundle sizes (minified + gzipped):
itty-router (AutoRouter): ~1 kB
itty-router (Router): <500 bytes
Hono (hono/tiny preset): ~3 kB
Hono (full): ~14 kB
# When to care:
# Workers free plan has 1 MB script limit
# Smaller bundles = faster cold start in some scenarios
# Most projects: the difference is irrelevant
itty-router Limitations
- Less TypeScript support than Hono (no automatic route type inference)
- No built-in middleware (CORS, logger require custom code)
- No multi-runtime support (Cloudflare Workers primary)
- Smaller ecosystem and community than Hono
worktop
Package: worktop
Weekly downloads: 30K
GitHub stars: 1.8K
Creator: Luke Edwards
Cloudflare-specific: Yes
worktop is a TypeScript-first Workers framework with built-in features for CORS, sessions, and typed route parameters.
Installation
npm install worktop
Basic Usage
import { Router } from 'worktop';
import * as CORS from 'worktop/cors';
const API = new Router();
// CORS middleware
API.add('OPTIONS', '*', CORS.preflight());
API.add('GET', '/users/:id', async (req, res) => {
const { id } = req.params; // Typed string
const user = await getUser(id);
if (!user) return res.send(404, { message: 'Not found' });
res.send(200, user); // Typed: automatically JSON-serializes
});
API.add('POST', '/users', async (req, res) => {
const body = await req.body.json<{ name: string; email: string }>();
const user = await createUser(body);
res.send(201, user);
});
export default {
fetch: API.run,
};
Typed Route Params
import { Router } from 'worktop';
const router = new Router();
// TypeScript knows req.params.id is a string
router.add('GET', '/items/:id', async (req, res) => {
const { id } = req.params; // string
// ...
});
// Multiple params
router.add('GET', '/org/:orgId/repo/:repoId/commit/:sha', async (req, res) => {
const { orgId, repoId, sha } = req.params; // All typed as string
// ...
});
worktop Limitations
- Cloudflare Workers specific (not multi-runtime)
- Smaller community than Hono
- Less actively maintained (lower release frequency)
- No equivalent of Hono's middleware ecosystem
Feature Comparison
| Feature | Hono | itty-router | worktop |
|---|---|---|---|
| Weekly downloads | 2M | 300K | 30K |
| Bundle size | ~14kB (full) | ~1kB (AutoRouter) | ~5kB |
| TypeScript support | Excellent | Good | Excellent |
| Multi-runtime | 9+ runtimes | Workers-focused | Workers-only |
| Built-in middleware | Yes (cors, logger, auth, etc.) | No | CORS, cache |
| Benchmarks | 402K req/s | 213K req/s | 197K req/s |
| RPC client | Yes (hono/client) | No | No |
| Route grouping | Yes | Partial | No |
| Zod integration | Yes (@hono/zod-validator) | No | No |
When to Use Each
Choose Hono if:
- You're building anything beyond a simple 5-route Worker
- TypeScript type safety and IDE support matter
- You want built-in middleware (CORS, auth, logging, rate limiting)
- Your Worker might need to run on multiple runtimes (Deno, Bun, Vercel)
- You need Hono's RPC client for type-safe client code
Choose itty-router if:
- Bundle size is a hard constraint
- Your Worker has 2-5 routes and minimal middleware needs
- You want the absolute simplest routing API
Choose worktop if:
- You want Cloudflare-specific typed session and request body helpers
- TypeScript route params typing is important
- You were already using worktop and don't need to migrate
Ecosystem and Community
Hono has built a genuinely impressive ecosystem in a short time. The @hono npm scope houses over 30 officially maintained packages: @hono/zod-validator, @hono/jwt, @hono/trpc-server, @hono/swagger-ui, @hono/node-server, and more. Third-party packages integrate with Drizzle ORM, Prisma, and other popular libraries seamlessly. The GitHub Discussions community is active with 1,000+ threads, and creator Yusuke Wada is highly responsive to issues. Cloudflare's own adoption — using Hono internally for D1's API surface and Workers dashboard — sends a strong signal about production trustworthiness.
itty-router's community is smaller but tightly focused. The documentation is excellent for a small library, and Kevin Whitley maintains it actively. The GitHub Discussions are helpful but the library is intentionally minimal — most questions are answered by the docs alone. There's no official plugin or middleware ecosystem because the library philosophy is "add what you need yourself."
worktop's trajectory has been flatter. It peaked around 2022-2023 and has seen slower iteration since. The GitHub issues have longer response times compared to Hono, and the ecosystem around it is limited to a handful of community packages. For new projects, worktop's appeal is primarily its clean API and Workers-native design philosophy, not a broad ecosystem.
When comparing npm download trends, Hono is growing at roughly 20% month-over-month while itty-router is flat-to-growing at 5-10% and worktop is slightly declining from its peak.
Real-World Adoption
Hono's production deployment story is strong. Beyond Cloudflare's internal use, it has been adopted by teams at companies across the edge computing ecosystem. It powers API backends deployed on Cloudflare Workers, Deno Deploy, Fastly Compute@Edge, and AWS Lambda Edge. The create-hono scaffolding tool makes it the de-facto starting point for edge API development in 2026. For type-safe API clients that sit on top of Hono, see Hono RPC vs tRPC vs ts-rest type-safe API clients 2026.
A typical production use case is a BFF (backend-for-frontend) layer running on Cloudflare Workers that proxies and transforms responses from origin services. Hono handles authentication middleware, response caching with Cache API, and request validation with Zod — all in a single Worker that serves millions of requests per day with no cold-start latency. For edge data stores that complement Hono's deployment model, see Cloudflare Durable Objects vs Upstash vs Turso edge databases 2026.
itty-router powers many small utilities: webhook endpoints, short URL redirectors, A/B testing scripts, and edge authentication middleware. Its bundle size advantage makes it particularly popular for Workers that get appended to larger scripts or deployed alongside other Worker resources. Companies with Workers-heavy architectures sometimes use itty-router for internal service-to-service routing where the external API already uses Hono.
worktop powers production apps at companies that built on it during 2021-2023. Migration to Hono is uncommon since worktop apps are generally small and stable — the cost of migrating doesn't outweigh the benefits for working code.
Developer Experience Deep Dive
Hono's TypeScript support is best-in-class for an edge router. The context object c is fully typed — c.env reflects your Env bindings, c.req.valid('json') returns the Zod-validated type, and the RPC client infers all route types automatically. IDE autocomplete works throughout. Error messages from TypeScript are clear when you get types wrong. The docs include TypeScript-first examples for every feature.
The debugging story is also solid. Hono's logger() middleware outputs structured request logs to console.log, which appears in the Cloudflare Workers dashboard and wrangler tail output. For local development, wrangler dev with @hono/node-server gives a full local development environment that closely mirrors Workers.
itty-router's TypeScript support is pragmatic. The route handler receives a Request (extended with matched params), and you get basic type inference for params. What's missing is the ability to type the full API surface the way Hono's RPC client does. For simple Workers, this is fine — you don't need end-to-end type safety for a 3-route webhook handler.
worktop's TypeScript integration is clean for route params and request body typing. The req/res pattern is explicitly typed rather than inferred, which means slightly more boilerplate but very predictable types.
Migration Guide
Migrating from itty-router or worktop to Hono is straightforward. The routing concepts map 1:1 — route methods, params, and middleware chains all work the same way. The main adjustment is switching from itty-router's auto-propagated args to Hono's c.env binding pattern, and from worktop's res.send() to Hono's c.json() / c.text() responses. Most migrations can be done incrementally — swap the router, then move middleware one piece at a time. The Hono documentation includes a migration guide specifically for itty-router users.
For new projects coming from Express or Fastify on Node.js, Hono's API will feel immediately familiar. The key mental shift is understanding that there's no separate req and res — instead, the single context object c contains both the request helpers and response methods.
The 2026 Recommendation
Hono is the clear choice for new projects. Its 2M weekly downloads and Cloudflare's internal adoption (D1, Workers Logs) are strong signals of production readiness. The multi-runtime support means your code isn't locked to Workers — you can run it locally on Bun or Node.js without changes.
itty-router remains valuable for extremely simple Workers where every byte counts. worktop serves its existing users well but isn't the right starting point in 2026.
Compare edge framework downloads on PkgPulse.
Testing Edge Workers
Testing Workers locally has improved significantly across all three router options. Cloudflare's wrangler dev runs a local instance of the Workers runtime that closely matches the production environment. For unit testing, @cloudflare/workers-sdk exports unstable_dev() which starts a real Workers runtime process in the test environment.
Hono works particularly well with vitest for unit testing because its handler functions are plain async functions that take a Request and return a Response. Testing is straightforward:
import { describe, it, expect } from 'vitest';
import app from './index';
describe('Users API', () => {
it('returns 404 for unknown user', async () => {
const res = await app.request('/users/999');
expect(res.status).toBe(404);
const data = await res.json();
expect(data.error).toBe('Not found');
});
});
The same pattern works for itty-router and worktop — their fetch handlers are tested by creating a synthetic Request and asserting on the Response. The Cloudflare Workers testing ecosystem has matured enough that local development and testing are reliable, which reduces the number of issues that only manifest in production.
Hono's Emerging Role Beyond Cloudflare Workers
While all three routers are primarily used for Cloudflare Workers, Hono's multi-runtime architecture has made it relevant in new contexts. In 2026, Hono is commonly used as the framework for Deno Deploy serverless functions, Bun backend applications, and Node.js API services where developers want Express-like ergonomics without the legacy overhead. The same codebase can deploy as a Cloudflare Worker for global edge distribution and as a Node.js service behind an internal load balancer — without code changes.
This portability has made Hono attractive for teams building platform-agnostic backend services that need to run in multiple deployment environments. The serve() function from @hono/node-server means a Hono app can run in a Docker container on any cloud provider, while the Cloudflare Workers export allows deploying the same app to the edge without a container. This flexibility is itty-router's and worktop's greatest weakness — both are fundamentally Workers-native with no comparable multi-runtime story.
Related: Hono vs Elysia for edge APIs, Best Node.js Background Job Libraries 2026, Best JavaScript Testing Frameworks 2026
Compare Hono, Itty-router, and Worktop package health on PkgPulse.