
TypeScript or nothing
One language from the phone to the database. Here's why every project I take on is TypeScript end to end, and why I stopped apologising for it.
Express shaped a generation of Node APIs. Here's why my new backends start with Hono instead, and the three places it actually changes how I build.

Express is the framework everyone learns first. It's also the one I quietly stopped starting projects with.
Not because Express is bad. It ran half the internet for a decade and it earned that. But the ground moved. We ship to the edge now. We write TypeScript by default. We expect the thing underneath us to know what a Response actually is. Express predates all of that, and you feel the gap on day one of a fresh build.
Here's the honest version of why my APIs start with Hono now.
With Express, your handler signature is (req, res) and both are mostly any until you bolt on @types and hope. With Hono, the types flow. Your route params, your validated body, your context, all of it is known at compile time.
import { Hono } from "hono"
const app = new Hono()
app.get("/posts/:id", (c) => {
const id = c.req.param("id") // string, inferred, no casting
return c.json({ id })
})That c.req.param("id") is typed because the route string is part of the type. Rename the param and the compiler catches every reference. That's the difference between finding a bug in your editor and finding it at 2am in production logs.
Pair it with a schema validator and the inference reaches all the way into your handler body.
import { zValidator } from "@hono/zod-validator"
import { z } from "zod"
const schema = z.object({ title: z.string().min(1) })
app.post("/posts", zValidator("json", schema), (c) => {
const body = c.req.valid("json") // { title: string }
return c.json(body, 201)
})No manual parsing. No req.body as CreatePostDto. The validated shape is the type.
Express assumes Node. Hono assumes the web standard Request and Response, which means the same code runs on Node, Bun, Cloudflare Workers, and a Next.js route handler without a rewrite.
| Express | Hono | |
|---|---|---|
| Runtime | Node only | Node, Bun, Workers, edge |
| Base type | Custom req/res | Web Request/Response |
| Router speed | Linear-ish | Trie, very fast |
| Bundle size | Heavier | Tiny |
When a client's traffic is spiky and global, moving the API to the edge is a config change, not a project. That flexibility has saved me a full migration more than once.
Express middleware mutates req and calls next(). It works, but the data flow is invisible. You never quite know what's on req by the time your handler runs.
Hono middleware is explicit. You set values on the context with a typed key, and you read them back typed. The chain reads like a sentence, and the compiler knows what each step added.
I'm not here to sell you a rewrite. If you have a mature Express app with a team that knows it cold, the framework is not your bottleneck. Ship features. And if you lean on a library that only ships Express middleware, staying put is the cheaper call.
Hono earns its place on new services, edge deploys, and anything where the type safety pays for itself over the life of the codebase. That's most of what I build. It might not be most of what you build, and that's fine.
Yes. It's used in production at real scale, it's actively maintained, and the API has been stable through its recent major versions. I've shipped client work on it without drama.
No. Hono mounts cleanly inside a Next.js route handler or alongside an existing service. Start with one new endpoint, feel the difference, then decide.
Smaller than Express, but the essentials are there: validation, auth, CORS, rate limiting. Because it speaks web standards, a lot of platform-native tooling works without a Hono-specific adapter.
Only if your users are spread out or your traffic spikes. For a single-region internal tool, the edge is a nice-to-have. The type safety is the reason to switch either way.
Express taught Node how to serve HTTP. Hono assumes you already know that and hands you type safety, portability, and speed on top. I still respect Express. I just don't start there anymore.
If you're weighing a backend for something new, I wrote about how I pick a stack, and if you want a second opinion on yours, tell me what you're building.
Prabir Singh
Full-stack engineer from Mumbai. Twenty years in sales, now I build products that sell. More about me or start a project.

One language from the phone to the database. Here's why every project I take on is TypeScript end to end, and why I stopped apologising for it.

Web, mobile, API, and shared packages in a single monorepo. Here's how I run it with Turborepo, and why one repo beats a folder full of them.

Server Components confuse people because the mental model is missing. Here's the one that finally makes the client/server split click, plus the rules that keep it clean.