Hono vs Express vs Bun for SaaS API Servers in 2026
A founder asked me last month whether the API for his product should be "on Hono or on Bun." I gave him a bad answer for about thirty seconds before I caught the problem in the question. Two of those three things are not competing with each other at all, and once you separate them the decision gets much smaller.
That confusion is the most common thing I see when someone is picking a backend for a SaaS product. It shows up in job posts, in stack diagrams, in the "what should I learn" threads. So before the benchmarks and the migration horror stories, the boring taxonomy, because everything downstream depends on it. If you want the underlying vocabulary first, my explainer on what a REST API actually is covers the request-and-response layer these tools all sit on top of.
Which of These Three Is Not a Framework?

Bun is a JavaScript runtime, not a web framework, so it competes with Node.js and Deno rather than with Hono or Express. Hono and Express are the two frameworks in the list. Bun is the thing they can run on, alongside Node. You can run Express on Bun. You can run Hono on Node. The question "Hono or Bun" is closer to "screwdriver or workbench" than to a real fork in the road.
| Hono | Express | Bun | |
|---|---|---|---|
| Category | Web framework | Web framework | JavaScript runtime |
| Competes with | Express, Fastify, Elysia | Hono, Fastify, Koa | Node.js, Deno |
| HTTP primitive | Web-standard Request / Response | Node req / res | Web-standard Request / Response |
| Where it runs | Workers, Deno, Bun, Lambda, Node | Node.js | Its own process |
| Minified size | Under 14kB (hono/tiny preset) | 572KB | N/A |
The size and portability numbers come from Hono's own documentation, which lists Cloudflare Workers, Fastly Compute, Deno, Bun, Vercel, Netlify, AWS Lambda, Lambda@Edge and Node.js as supported targets. That list is the actual product. Hono is not primarily a faster Express; it is an Express-shaped API that survives being deployed somewhere Node cannot go.
So the real decision is two decisions stacked: which runtime hosts the process, and which framework shapes the handlers. Answer them in that order.
How Fast Is Hono Compared to Express, Really?

Hono handles roughly two to three times the requests per second Express does in hello-world benchmarks, and that gap mostly evaporates once a database is involved. Encore's 2026 comparison of NestJS, Fastify and Hono puts NestJS on the Express adapter at about 28k req/sec, Fastify at about 45k, Hono on Node at about 70k, and Hono on Bun at about 80k. Better Stack's guide independently pegs Fastify at 40,000+ requests per second on a single Node process, which lines up.
Now the part the benchmark charts leave out. Encore's own conclusion on those numbers is that "in practice, your database and network I/O dominate framework overhead." A single unindexed Postgres query costs more milliseconds than the entire routing layer costs microseconds. If your handler does auth, one read, one write and a serialisation pass, you are not measuring Hono against Express anymore. You are measuring your database.
How many requests per second does your API actually serve at peak? If you cannot answer that from a dashboard, the table above is entertainment rather than input.
Where the throughput gap does matter is cold starts and bundle size, which is a serverless concern rather than a server concern. A 14kB framework boots faster in a Worker than a 572KB one, every single time. That is a real argument, and it is a different argument from raw req/s. My glossary entry on serverless walks through why per-invocation startup cost dominates in that model.
Express Is Not Dead, and the Release History Says So

Express 4 shipped a maintenance release on 11 May 2026 and still has active security support, which is not what a dead project looks like. According to endoflife.date's Express tracker, 4.22.2 landed on that date, Express 5.0 arrived on 9 September 2024, and 5.2.1 shipped on 1 December 2025. The framework people keep writing obituaries for is on a normal release cadence.
I bring this up because the migration math is usually worse than the pitch. Hono and Express have genuinely different middleware contracts: Express hands you (req, res, next), Hono hands you (c, next) with a single context object and an awaited next(). There is no official adapter that bridges them. The proposal for one, honojs/hono issue #3293, has been open since 18 August 2024, and the blocker stated in the thread is exactly what you would expect: "Hono's Context object doesn't directly map to Express's req and res objects."
Which means every piece of Express middleware you depend on is a rewrite, a replacement, or a reason not to move. Session handling. Passport strategies. That one custom error handler nobody has read since 2021. Every port I have scoped came in over estimate, and the overrun was in the middleware surface rather than the routes.
None of that makes Express the right pick for a new project. It makes Express a defensible pick for an existing one, which is a claim worth separating from framework fashion.
Where Does Bun Actually Break?
Bun breaks on native addons, and the three that bite backend teams hardest are bcrypt, argon2 and canvas. Most of a typical SaaS dependency tree runs fine. The 2026 Bun compatibility audit by Alex Cloudstar is the most honest inventory I have found, and it is worth reading before you commit a production service.
The short version, with the fixes that exist:
- bcrypt uses native bindings and does not run. Swap in
bcryptjs, or useBun.password, which is built in and better. - argon2 fails for the same reason. You need a pure-JS alternative or the Bun-native path.
- canvas is broken with, in the audit's words, no clean workaround. If you generate images, invoices or OG cards server-side, this one is a hard stop rather than a papercut.
- better-sqlite3 is not so much broken as replaced.
bun:sqliteships in core and does the same job.
Also fragile: node:vm and node:cluster are partially supported. If your process model depends on clustering across cores, test that specifically before you plan around it.
Bun 1.3 Made the Framework Question Smaller
The most interesting recent change is not on the framework side at all. Bun 1.3, released 10 October 2025, pulled a pile of things into the runtime that used to require dependencies: Bun.serve() gained parameterized :id routes, catch-all routes and method-specific handlers, and the runtime now ships a unified Bun.SQL client covering Postgres, MySQL, MariaDB and SQLite, plus a Redis client with 66 commands that the release notes clock at 7.9x the throughput of ioredis.
Read that as a strategy, not a feature list. For a small internal service with a dozen endpoints, Bun 1.3 removes the reason to install a framework in the first place. Routing, database access and caching all come from the runtime. That is a genuinely new option in this comparison and it did not exist eighteen months ago.
It does not scale up gracefully, though. The moment you want composable middleware, typed route groups, request validation and an RPC client, you want Hono. Bun's router is a router. Hono is a framework, and the difference shows up around endpoint thirty.
The Testing Story
This is where Hono quietly wins. app.request(path, options, env) builds a Request, passes it straight to your app, and hands back the Response — no server to boot, no supertest, no port. Hono's testing guide shows the whole API in about four lines. Express testing is fine. It is just never this small.
Mounting Hono Inside Next.js
If you are already on Next.js, Hono replaces route handlers rather than sitting beside them. The setup, per Hono's Next.js guide:
- Create
app/api/[[...route]]/route.ts. The optional catch-all segment is what lets one file own every API path. - Instantiate with a base path:
const app = new Hono().basePath('/api'). - Define routes on that instance the normal way, with
.get(),.post()and friends. - Export the method handlers:
export const GET = handle(app)andexport const POST = handle(app), wherehandlecomes fromhono/vercel.
What you get out of it is a real router with middleware composition instead of one file per path, and end-to-end types via Hono's RPC client if you use the validator. That second part is the actual draw for me, and it only pays off if your codebase is typed end to end already.
How I'd Pick This Week
For a new SaaS API where you control the runtime, I would start on Hono and run it on Bun, and I would not treat that as a permanent commitment. Hono's web-standard handlers move to Node, Workers or Lambda later without a rewrite, which is the cheapest optionality available in this category. If any dependency needs a native addon, run the same Hono app on Node instead and lose nothing but a few thousand req/s you were never going to notice.
For an existing Express service that works: leave it. Express 5 is maintained, your middleware is paid for, and the migration will cost more than the benchmark delta returns.
There is a third case that is easy to forget. Sometimes the framework decision does not exist. On BookBed, the entire server-side HTTP surface that ever mattered was the Stripe webhook that keeps accountType in lockstep with subscription status, and Firebase owned that endpoint. No framework was chosen because none was needed. Actually, let me be more precise: a framework decision was made, by the platform, before I got a vote. That is a normal outcome for a product where the client does most of the work, and it is worth checking whether it describes yours before you spend a week on this comparison. The SaaS MVP stack guide walks the same decision from the other direction, starting from the product rather than the runtime.
So: go open your APM and find your p95 for one real endpoint, then find what share of it is spent outside your database. If that share is under ten percent, you already know which of these three questions is worth your afternoon. Which one is it?
