![Hono Large Logo](https://hono.dev/images/logo-large.png)

Hono Large Logo

Why Hono Actually Works in Production

I've been shipping JavaScript to production for like 6 years now. Every framework pisses me off somehow. Express is slow as hell and pulls in more deps than a crypto project. Next.js cold starts take forever - I swear it's longer than my coffee break sometimes. Fastify's decent but you're stuck on Node.

Yusuke Wada built Hono in December 2021 because he was tired of frameworks that couldn't run on Cloudflare Workers without some bullshit adapter layer. You can read the full story here.

Your Code Actually Runs Everywhere

Most "universal" frameworks are lying to you. Express doesn't work on Deno. Next.js edge runtime is missing half the Node APIs you actually need.

Hono uses Web Standards APIs - same Request/Response objects from browser dev. Write it once, runs everywhere:

I've deployed the same Hono app to all these platforms. Same code. No adapter bullshit. Examples are here if you want to see it.

Bundle Size Will Ruin Your Serverless Day

Serverless cold starts will ruin your day. Express is like 579KB before you add anything useful. Hono is 12KB total.

Bundle Size Comparison

On Workers your API responds in 50ms instead of 2 seconds. On Lambda you're not burning money on 500MB RAM for hello world. Read serverless patterns if you want the theory.

Zero Dependencies = Zero Headaches

Hono has zero dependencies. Actually zero. No npm audit warnings every Tuesday. No left-pad bullshit breaking your build.

Routing, middleware, TypeScript types - it's all built in. Install hono, you're done. No dependency tree that looks like spaghetti.

TypeScript Support That Doesn't Make You Cry

TypeScript support doesn't suck. Route params are typed. Request bodies are typed. Context variables are typed. RPC generates types automatically.

Hono TypeScript Support

app.get('/users/:id', (c) => {
  const id = c.req.param('id') // string, not any
  return c.json({ user: { id } })
})

Express types are garbage - everything's any unless you write type guards for 20 lines.

Performance That Actually Matters in Production

Way faster than Express - Hono hits hundreds of thousands req/sec on Workers. Express dies around 15k.

Real companies use this - Cloudflare runs it internally for Workers KV, D1, Queues. Nodecraft uses it for game servers, Unkey for API auth.

Gotcha: Cold starts on Node 18.2 can spike to 200ms - module resolution got fucked. Found out during a demo that froze for 3 seconds while the client stared at me. Use 18.15+ or just use Bun/Deno.

JSX That Actually Just Works

Want server-side rendering? Just write JSX. No webpack, no babel config, no "use client" React bullshit.

const Layout = ({ children }) => (
  <html><body>{children}</body></html>
)

app.get('/', (c) => c.html(<Layout><h1>Works</h1></Layout>))

Learned this at 3am during a deployment - tried Next.js SSR on Workers, spent 4 hours on React hydration mismatches and Warning: Text content did not match errors. Switched to Hono JSX, deployed in 10 minutes.

Hono Quick Development

Current version is stable. 26k GitHub stars and actively maintained. Not a weekend project.

Version gotcha: Check the releases page before deploying. Security fixes drop fast, edge runtimes don't auto-update.

Hono vs The Usual Suspects

Feature

Hono

Express

Fastify

Next.js

Bundle Size

~12KB

579KB+

~200KB

400KB+

TypeScript

Built-in

@types/express is garbage

Pretty good

React-level good

Runtime Support

Workers, Deno, Bun, Node

Node only

Node only

Node + "edge"

Cold Starts

Under 50ms

2+ seconds

~500ms

3+ seconds

Stack Overflow

Growing community

Every answer exists

Decent help

React complexity

Performance

Way faster

~15k req/sec

~45k req/sec

Varies wildly

Dependencies

Zero

npm audit nightmares

Some

React ecosystem

Memory Usage

Minimal

Hungry

Moderate

RAM destroyer

How Hono Actually Works (And Where It Breaks)

Web Standards APIs - The Good and Bad

Hono uses Web Standards APIs - same Request/Response objects from browser code. This is why it works everywhere, but also why some shit breaks. Web API compatibility varies by runtime.

app.get('/api/users', (c) => {
  return c.json({ users: [] }) // Standard Response, works everywhere
})

The good: Your browser dev skills transfer directly. Same request/response objects you already know.

The gotcha: Node packages expecting req.connection or Node internals won't work. Had to rewrite logging middleware when migrating from Express - kept getting ReferenceError: process is not defined on Workers. Spent 3 hours tracking that shit down. Node compat guide helps.

Router Performance - Why It's Actually Fast

Hono has multiple routers, the default RegExpRouter is fast:

  • RegExpRouter (Default): Compiles routes to regex patterns. Hits 400k+ req/sec.
  • SmartRouter: Picks the best algorithm based on your routes. Probably overkill.
  • LinearRouter: Simple array matching. For <20 routes and minimal startup time.
  • PatternRouter: Uses URLPattern API. Future-proof but slower.

Unless you're doing 100k+ req/sec, just use the default. Never needed to change it.

Middleware That Doesn't Suck

Express middleware runs in a global chain where order matters and debugging sucks. Hono's middleware is context-scoped:

app.use('/admin/*', async (c, next) => {
  const token = c.req.header('authorization')
  if (!token) return c.text('Unauthorized', 401)
  
  const user = await validateToken(token) // This can fail
  c.set('user', user) // TypeScript knows the type
  await next()
})

app.get('/admin/dashboard', (c) => {
  const user = c.get('user') // TypeScript: User | undefined
  return c.json({ message: `Hello ${user.name}` })
})

What's better: Context variables are typed. No more req.user: any from Express.

What breaks: If your auth middleware throws instead of returning an error response, the error boundary catches it. Learned this when our JWT library started throwing instead of returning null - took 2 hours to figure out why auth stopped working after a dependency update. JsonWebTokenError: invalid signature everywhere but no clue why.

Built-in Stuff That Actually Works

JSON parsing is built in and fast. No express.json() needed:

app.post('/api/data', (c) => {
  const body = await c.req.json() // Just works, properly typed
  return c.json({ received: body })
})

File serving works across runtimes with proper headers:

import { serveStatic } from 'hono/cloudflare-workers'

app.use('/static/*', serveStatic({ root: './public' }))

Compression is built in:

import { compress } from 'hono/compress'
app.use('*', compress())

JSX Without the Build Hell

This works without webpack, babel, or any build shit:

const Layout = ({ children }) => (
  <html>
    <head><title>My App</title></head>
    <body>{children}</body>
  </html>
)

app.get('/', (c) => c.html(<Layout><h1>Hello World</h1></Layout>))

The magic: Hono includes its own JSX runtime. No React dependency.

The limitation: It's not React. No hooks, no client hydration. Server-side only.

RPC That Actually Generates Types

The killer feature nobody talks about:

// Server side
const routes = app
  .get('/posts/:id', (c) => {
    const id = c.req.param('id')
    return c.json({ post: { id, title: 'Hello' } })
  })
  .post('/posts', (c) => {
    // ... validation logic
    return c.json({ created: true }, 201)
  })

// Client side - types are generated automatically
import { hc } from 'hono/client'
const client = hc<typeof routes>('http://localhost:3000')

// This is fully typed, including status codes
const response = await client.posts[':id'].$get({ param: { id: '123' } })
const post = await response.json() // TypeScript knows this shape

Why this matters: Full-stack type safety without GraphQL complexity or tRPC overhead.

When it breaks: Complex nested routes with dynamic segments can confuse the type generation. Had to simplify some API paths.

Testing Without Pain

No need to spin up servers for testing:

import { testClient } from 'hono/testing'

test('Creates user', async () => {
  const client = testClient(app)
  const res = await client.users.$post({ json: { name: 'test' } })
  
  expect(res.status).toBe(201)
  const data = await res.json()
  expect(data.created).toBe(true)
})

Tests run fast because there's no TCP overhead. Debugging failed requests sucks since there's no network tab to inspect. Had to add console.log everywhere when a test started failing - basically printf debugging like it's 1995.

Questions Developers Actually Ask

Q

Is this another weekend project or can I bet my job on it?

A

Current version is stable. Cloudflare uses it internally, companies like Nodecraft and Unkey run production apps on it. 26k GitHub stars and regular releases since December 2021.But it's newer than Express. Fewer Stack Overflow answers when you're debugging at 3am. Smaller community means fewer tutorials. It's stable, but you'll hit undocumented edge cases.

Q

Will migrating from Express break everything?

A

Probably not. The API is deliberately Express-like:typescript// Expressapp.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') })})What stays the same: Route definitions, middleware concepts, basic patterns.What breaks: Node-specific middleware, packages expecting req.connection, custom Express plugins. util.promisify() calls blow up on Workers with TypeError: Cannot read properties of undefined. Budget 2-3 days for migration gotchas on a medium app.

Q

Does it actually work on all these runtimes or is that marketing bullshit?

A

It works.

I've deployed the same Hono codebase to:

  • Cloudflare Workers (best performance)
  • Deno Deploy (easiest deployment)
  • Node.js (legacy compatibility)
  • AWS Lambda (expensive but works)Same code, no runtime adapters needed.

Catch: you can't use Node-only packages like fs on edge runtimes.

Q

What happens when I need middleware that doesn't exist yet?

A

You write it yourself. Hono's middleware ecosystem is smaller than Express's 15-year head start. Upside: built-in middleware covers most common needs (JWT, CORS, compression, validation).Writing custom middleware is straightforward:typescriptconst customAuth = async (c, next) => { const token = c.req.header('authorization') if (!token) return c.text('Unauthorized', 401) // Your auth logic here await next()}

Q

How's the TypeScript experience compared to Express?

A

Night and day better.

Express with TypeScript is community-maintained garbage:```typescript// Express

  • types are liesapp.get('/users/:id', (req, res) => { const id = req.params.id // any, not string req.user // Property 'user' does not exist})// Hono
  • types actually work app.get('/users/:id', (c) => { const id = c.req.param('id') // string, properly typed const user = c.get('user') // User | undefined, typed context})```Hono's RPC feature generates end-to-end types from server to client. No more maintaining separate API type definitions.
Q

Will cold starts actually be faster or is that benchmark bullshit?

A

Cold starts are faster.

Hono is 12KB vs Express at 579KB. In serverless:

  • Cloudflare Workers: 50ms vs 2+ seconds
  • AWS Lambda: 200ms vs 1+ second
  • Vercel Edge:

Similar improvementsThe benchmarks reflect real deployment performance, not synthetic tests.

Q

Can I use it for server-side rendering without losing my mind?

A

Yes, but it's not React. Hono's JSX is server-side only:typescriptconst Page = ({ title, children }) => ( <html> <head><title>{title}</title></head> <body>{children}</body> </html>)app.get('/', (c) => c.html(<Page title="Hello">Content</Page>))Pros: No build step, no webpack config, no hydration complexity.Cons: No client-side interactivity, no hooks, no React ecosystem.

Q

What about databases and ORMs?

A

Use whatever works on your target runtime:

  • Node.js/Deno: Prisma, Drizzle ORM, raw SQL
  • Cloudflare Workers: D1 (SQLite), Turso, PlanetScale
  • Universal: Drizzle ORM works everywhereHono doesn't care about your data layer
  • it's just a web framework.
Q

How do I debug when things go wrong?

A

Error handling is solid with app.onError():```typescriptapp.on

Error((err, c) => { console.error('Shit broke:', err) return c.text('Internal Server Error', 500)})```But debugging is harder than Express:

  • Fewer tutorials online
  • Edge runtime debugging tools are limited
  • Stack traces in Workers are cryptic
  • `TypeError:

Cannot read property 'xyz' of undefined at worker.js:1:1` tells you nothing useful

Q

Should I use this for my next project?

A

Use Hono if:

  • You're deploying to Cloudflare Workers or similar edge platforms (this is the main reason)
  • Bundle size and cold start performance actually matter to your users
  • You're tired of Express Type

Script being garbage

  • You're building APIs, not full-stack React appsStick with Express if:
  • Your team knows Express well and shipping fast matters more than performance
  • You need that one specific middleware that only exists for Express
  • You're building traditional server-rendered applications
  • "It's what we've always used" and your boss won't let you change it

Related Tools & Recommendations

tool
Similar content

Express.js - The Web Framework Nobody Wants to Replace

It's ugly, old, and everyone still uses it

Express.js
/tool/express/overview
100%
compare
Similar content

Hono, Express, Fastify, Koa: Node.js Framework Speed & Selection

Hono is stupidly fast, but that doesn't mean you should use it

Hono
/compare/hono/express/fastify/koa/overview
96%
tool
Similar content

Fastify Overview: High-Performance Node.js Web Framework Guide

High-performance, plugin-based Node.js framework built for speed and developer experience

Fastify
/tool/fastify/overview
93%
tool
Similar content

Koa.js Overview: Async Web Framework & Practical Use Cases

What happens when the Express team gets fed up with callbacks

Koa.js
/tool/koa/overview
92%
tool
Similar content

Bun JavaScript Runtime: Fast Node.js Alternative & Easy Install

JavaScript runtime that doesn't make you want to throw your laptop

Bun
/tool/bun/overview
78%
compare
Recommended

I Benchmarked Bun vs Node.js vs Deno So You Don't Have To

Three weeks of testing revealed which JavaScript runtime is actually faster (and when it matters)

Bun
/compare/bun/node.js/deno/performance-comparison
75%
tool
Similar content

Hono Performance Optimization: Eliminate Cold Starts & API Lag

Optimize Hono API performance by tackling cold starts, common middleware mistakes, and other bottlenecks. Learn how to build faster, more efficient Hono applica

Hono
/tool/hono/performance-optimization
55%
tool
Similar content

Fresh Framework Overview: Zero JS, Deno, Getting Started Guide

Discover Fresh, the zero JavaScript by default web framework for Deno. Get started with installation, understand its architecture, and see how it compares to Ne

Fresh
/tool/fresh/overview
50%
tool
Similar content

Django: Python's Web Framework for Perfectionists

Build robust, scalable web applications rapidly with Python's most comprehensive framework

Django
/tool/django/overview
47%
tool
Similar content

Hono Production Deployment Guide: Best Practices & Monitoring

Master Hono production deployment. Learn best practices for monitoring, database connections, and environment variables to ensure your Hono apps run stably and

Hono
/tool/hono/production-deployment
47%
tool
Similar content

FastAPI - High-Performance Python API Framework

The Modern Web Framework That Doesn't Make You Choose Between Speed and Developer Sanity

FastAPI
/tool/fastapi/overview
46%
tool
Similar content

Actix Web: Rust's Fastest Web Framework for High Performance

Rust's fastest web framework. Prepare for async pain but stupid-fast performance.

Actix Web
/tool/actix-web/overview
43%
tool
Similar content

Axum Web Framework Overview: Why It's Better & How It Works

Routes are just functions. Error messages actually make sense. No fucking DSL to memorize.

Axum
/tool/axum/overview
40%
tool
Similar content

Webpack: The Build Tool You'll Love to Hate & Still Use in 2025

Explore Webpack, the JavaScript build tool. Understand its powerful features, module system, and why it remains a core part of modern web development workflows.

Webpack
/tool/webpack/overview
40%
tool
Similar content

Node.js Memory Leaks & Debugging: Stop App Crashes

Learn to identify and debug Node.js memory leaks, prevent 'heap out of memory' errors, and keep your applications stable. Explore common patterns, tools, and re

Node.js
/tool/node.js/debugging-memory-leaks
39%
tool
Similar content

Qwik Overview: Instant Interactivity with Zero JavaScript Hydration

Skip hydration hell, get instant interactivity

Qwik
/tool/qwik/overview
39%
tool
Similar content

GraphQL Overview: Why It Exists, Features & Tools Explained

Get exactly the data you need without 15 API calls and 90% useless JSON

GraphQL
/tool/graphql/overview
37%
tool
Similar content

SolidJS: React Performance & Why I Switched | Overview Guide

Explore SolidJS: achieve React-like performance without re-renders. Learn why I switched from React, what it is, and advanced features that save time in product

SolidJS
/tool/solidjs/overview
36%
howto
Similar content

Bun Production Deployment Guide: Docker, Serverless & Performance

Master Bun production deployment with this comprehensive guide. Learn Docker & Serverless strategies, optimize performance, and troubleshoot common issues for s

Bun
/howto/setup-bun-development-environment/production-deployment-guide
35%
tool
Similar content

Node.js Production Debugging Guide: Resolve Crashes & Memory Leaks

When your Node.js app crashes at 3 AM, here's how to find the real problem fast

Node.js
/tool/node.js/production-debugging
35%

Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization