Hono: the framework that made me mass-delete my Express middleware
I had a Cloudflare Worker that did one thing: validate a JWT, hit a database, return JSON. Fifty lines of logic. The node_modules folder for its dev dependencies was 180MB. The cold start time was embarrassing. I knew this was wrong, the way you know a leaky faucet is wrong — you hear it every night but fixing it means touching plumbing.
Then someone on Twitter said “just use Hono” the way people say “just use Linux.” I rolled my eyes and tried it anyway.
The entire framework installed in under a second. My Worker went from fourteen dependencies to two. Cold starts dropped to numbers I’d previously associated with static files, not server logic. I felt like I’d been carrying a backpack full of rocks and someone just unzipped it.
The part where I understood the trick
Hono doesn’t invent a runtime. It doesn’t wrap Node’s http module in six layers of abstraction. It builds on Web Standards — the same Request and Response objects your browser already knows. That’s the whole trick.
import { Hono } from "hono";
const app = new Hono();
app.get("/api/user/:id", async (c) => {
const id = c.req.param("id");
const user = await getUser(id);
return c.json(user);
});
export default app;
If you’ve ever written a fetch handler, you already know Hono’s mental model. There’s no req.query vs req.params vs req.body guessing game. No res.send vs res.json vs res.end confusion. Context in, response out. That’s it.
Why this matters more than you think
The Web Standards bet is what makes Hono run everywhere. Same code deploys to Cloudflare Workers, Deno Deploy, Bun, AWS Lambda, Vercel Edge Functions, and yes, plain Node.js. Not “compatible with some quirks.” Actually the same file.
| Framework | Runtime lock-in | Cold start | Approach |
|---|---|---|---|
| Express | Node.js only | Heavy | Wraps Node http module |
| Fastify | Node.js only | Medium | Optimized Node http |
| Hono | Anywhere | Minimal | Web Standards native |
The runtime portability isn’t just theoretical. I wrote an API on Cloudflare Workers, then six months later moved it to Bun because I wanted WebSocket support that wasn’t available on Workers yet. Changed the entry point. Kept the routes. Kept the middleware. Kept my sanity.
The middleware situation
Hono’s middleware is where the personality shows. Built-in JWT validation, CORS, ETag, compression, Bearer auth — all in single-import, zero-dependency packages. No npm install passport passport-jwt passport-local express-session connect-mongo chain of dependencies where each one pulls in forty more.
import { Hono } from "hono";
import { jwt } from "hono/jwt";
import { cors } from "hono/cors";
const app = new Hono();
app.use("/api/*", cors());
app.use("/api/*", jwt({ secret: "mySecret" }));
app.get("/api/protected", (c) => {
const payload = c.get("jwtPayload");
return c.json({ user: payload.sub });
});
Twelve lines. Auth and CORS. No configuration object three screens tall.
The honest part
Hono is not Express. The ecosystem is smaller. If you need a specific OAuth provider integration, you might write it yourself. The community is growing fast — nearly 30k stars in three years — but it’s still young compared to Express’s decade-plus ecosystem.
Type inference in the RPC mode is brilliant but opinionated. If your team doesn’t like Zod-style validation baked into route definitions, you’ll fight the framework instead of enjoying it.
And documentation, while good, assumes you already know what you’re doing with web APIs. If you’re learning backend development for the first time, Express still has more tutorials, Stack Overflow answers, and blog posts explaining every edge case. Hono’s docs explain what to do but sometimes skip why you’d want to.
The thing I can’t stop thinking about
The web platform is slowly becoming the universal runtime. Deno, Bun, Cloudflare Workers, even Node.js — they’re all converging on Web Standards. Hono bet on that convergence before it was obvious. Every month that passes, another runtime adds fetch support, and Hono’s approach looks less contrarian and more inevitable.
I deleted my Express boilerplate repo last month. It was a template I’d maintained for four years, with session handling, rate limiting, error middleware, and a README I was quietly proud of. I replaced it with thirty lines of Hono. The README now says “see hono.dev.”
Sometimes the best code you’ll ever write is the code you delete.
honojs/hono · MIT · 29k stars · docs