TL;DR: Hono is a modern web framework for JavaScript and TypeScript that works on every major runtime — Cloudflare Workers, Vercel Edge, Deno, Bun, and Node.js. It's faster than Express, TypeScript-first, and designed for the edge-first world. AI coding tools increasingly suggest it for new projects because the code it generates is cleaner, more type-safe, and deploys anywhere without friction. If you're starting a new backend project in 2026, Hono is worth understanding before you default to Express.

What Is Hono, Really?

The name "Hono" means "flame" in Japanese. The framework lives up to the name — it's built for speed and designed to be small. The whole core is under 14KB. But size isn't the point. The point is that it runs everywhere.

Express — the framework most backend tutorials default to — was built in 2010, before Cloudflare Workers existed, before edge computing was a thing, before TypeScript became the default way people write JavaScript. Express runs on Node.js and Node.js only. That was fine for a long time. It's increasingly a constraint.

Hono was built from scratch for the modern runtime landscape. You write the same application code, and the framework handles running it on:

  • Cloudflare Workers — serverless functions that run at the network edge, closer to your users
  • Vercel Edge Functions — Vercel's edge runtime for ultra-fast API responses
  • Deno Deploy — Deno's cloud platform
  • Bun — the fast new JavaScript runtime that's eating into Node.js's market share
  • Node.js — the classic, when you need it
  • AWS Lambda — serverless functions on AWS

You swap the runtime adapter (a few lines of code) and your entire application works elsewhere. That portability is not something Express gives you at all.

Think of it like this: Express is a great power drill. It's reliable, everyone has one, and it works great as long as you have a wall outlet. Hono is a cordless drill. It's just as good, often faster, and works wherever you are — whether there's an outlet or not.

Hono vs. Express: The Comparison You Actually Need

If you've read our guide on what Express is, you know the basics: Express is a minimal Node.js framework that lets you handle HTTP requests, define routes, and wire up middleware. It's been the default backend framework for JavaScript developers for over a decade.

Hono does all of the same things. The API is intentionally similar. Here's the same "hello world" API route in both:

// Express
const express = require('express')
const app = express()

app.get('/', (req, res) => {
  res.json({ message: 'Hello World' })
})

app.listen(3000)
// Hono
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => {
  return c.json({ message: 'Hello World' })
})

export default app

The structure is the same. Routes work the same way. If you've done anything in Express, Hono clicks immediately. The differences are in what happens under the hood — and in what doesn't work at all.

The key differences

TypeScript support. Express was written in JavaScript and TypeScript support was added later via community-maintained type definitions (@types/express). The types are good but they weren't designed in from the start, so there are gaps. Hono is written in TypeScript from the ground up. Every part of it — request types, response helpers, middleware signatures — has proper types baked in. When AI generates Hono code, it produces code that TypeScript can actually verify, which means fewer runtime surprises.

Performance. Hono consistently benchmarks 5–10x faster than Express on edge runtimes. On Cloudflare Workers benchmarks, Hono handles hundreds of thousands of requests per second where Express alternatives struggle. Part of this is the leaner codebase; part of it is that Hono uses the standard Web APIs (Request, Response) that modern runtimes are optimized for, rather than Node.js's older http module abstractions.

Runtime portability. Express only runs on Node.js. Hono runs on any runtime that implements the WinterCG standard (the Web-interoperable Runtimes Community Group specification). That's an increasing list: Cloudflare Workers, Deno, Bun, and edge runtimes on every major cloud.

Bundle size. Express and its dependencies add up to megabytes. Hono's core is 13KB. This matters enormously on edge runtimes where bundle size directly affects cold start time — smaller bundles start faster.

Ecosystem maturity. Express wins here, clearly. Express has been around since 2010 and has thousands of community middleware packages, tutorials, Stack Overflow answers, and hiring pools. Hono launched in 2021 and is growing fast but can't match Express's depth yet. If you're learning backend for the first time and your team all knows Express, Express is still a defensible choice.

Here's the honest breakdown:

Choose Hono when: You're starting a new project, deploying to Cloudflare Workers or edge runtimes, using TypeScript, or building an API that needs to be fast and small.

Choose Express when: Your team already knows it, you need a specific Express middleware package that doesn't have a Hono equivalent, or you're adding to an existing Express app.

Why AI Tools Are Suggesting Hono Now

If you're using Claude Code, Cursor, or Copilot to scaffold new projects and they're generating Hono instead of Express, there's a reason — and it's not arbitrary.

Prompt you might have used:

"Set up a REST API for a task management app. I want routes to create, read, update, and delete tasks. Use TypeScript."

A few years ago, that prompt would reliably produce Express code. Now AI tools are increasingly likely to produce Hono code. Here's why:

TypeScript-first means better AI output. When AI generates TypeScript code with a TypeScript-native framework, the types align. Express TypeScript types are patched on — sometimes the AI generates code that type-checks on the surface but breaks at runtime because the underlying types weren't designed to fit together. Hono's built-in types give the AI a tighter contract to work within, producing code that's more likely to work without edits.

Modern patterns are cleaner. Express carries historical baggage — the req/res pattern, the callback-style middleware chain, the need to remember res.send() vs res.json() vs res.end(). Hono has a single context object (c) with consistent helper methods. AI can generate more consistent, correct Hono code because there are fewer "it depends" edge cases in the API.

Edge deployment is increasingly the default. Vercel and Cloudflare have become the dominant deployment targets for new JavaScript projects. Both platforms have native Hono support and official Hono examples. When AI tools infer "I should generate code that deploys well to where this person is probably deploying," Hono comes up naturally.

The community momentum is visible in training data. GitHub stars, Stack Overflow activity, and documentation quality all feed into what AI tools recommend. Hono crossed 25,000 GitHub stars in 2025 and is growing. The AI has seen enough Hono code, tutorials, and praise to confidently suggest it for appropriate use cases.

Building a REST API with Hono: Real Example

Let's build something real. A simple task management REST API — the same kind of thing you'd build to learn Express. CRUD operations: create a task, get all tasks, get one task, update it, delete it.

First, install Hono. If you're on Bun (the fastest option locally):

bun create hono my-api
cd my-api
bun install

Or with Node.js and npm:

npm create hono@latest my-api
cd my-api
npm install

Now here's the full tasks API. This is production-ready structure — not a "hello world" that falls apart when you try to extend it:

import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'

// Simple in-memory store for this example
// In production you'd replace this with a database
type Task = {
  id: string
  title: string
  completed: boolean
  createdAt: string
}

const tasks: Task[] = []
let nextId = 1

const app = new Hono()

// Middleware — runs on every request
app.use('*', logger())
app.use('*', cors())

// GET /tasks — list all tasks
app.get('/tasks', (c) => {
  return c.json({ tasks })
})

// GET /tasks/:id — get one task
app.get('/tasks/:id', (c) => {
  const id = c.req.param('id')
  const task = tasks.find(t => t.id === id)

  if (!task) {
    return c.json({ error: 'Task not found' }, 404)
  }

  return c.json({ task })
})

// POST /tasks — create a task
app.post('/tasks', async (c) => {
  const body = await c.req.json()

  if (!body.title || typeof body.title !== 'string') {
    return c.json({ error: 'title is required' }, 400)
  }

  const task: Task = {
    id: String(nextId++),
    title: body.title,
    completed: false,
    createdAt: new Date().toISOString()
  }

  tasks.push(task)
  return c.json({ task }, 201)
})

// PATCH /tasks/:id — update a task
app.patch('/tasks/:id', async (c) => {
  const id = c.req.param('id')
  const taskIndex = tasks.findIndex(t => t.id === id)

  if (taskIndex === -1) {
    return c.json({ error: 'Task not found' }, 404)
  }

  const body = await c.req.json()
  const task = tasks[taskIndex]

  if (body.title !== undefined) task.title = body.title
  if (body.completed !== undefined) task.completed = body.completed

  return c.json({ task })
})

// DELETE /tasks/:id — delete a task
app.delete('/tasks/:id', (c) => {
  const id = c.req.param('id')
  const taskIndex = tasks.findIndex(t => t.id === id)

  if (taskIndex === -1) {
    return c.json({ error: 'Task not found' }, 404)
  }

  tasks.splice(taskIndex, 1)
  return c.json({ message: 'Task deleted' })
})

export default app

A few things to notice here that are different from Express:

The context object c. Instead of separate req and res parameters, Hono uses a single context object. c.req is the request. c.json(), c.text(), and c.html() are the response helpers. This is cleaner — there's one thing to think about, not two.

You return the response. In Express you call res.json(data) as a side effect. In Hono you return c.json(data). This makes the control flow much more obvious — the function literally returns a response. It also prevents a common Express bug where you forget to return after sending a response and accidentally send two.

Middleware is imported from hono/ subpaths. Hono ships with built-in middleware for common needs: hono/cors, hono/logger, hono/bearer-auth, hono/jwt, and more. No separate npm packages needed for the basics.

Middleware, Routing, and Validation in Hono

Understanding middleware is key to using any web framework well. In Hono, middleware works the same way it does in Express conceptually — it's a function that runs before (or after) your route handlers — but the syntax is slightly different.

Custom middleware

Here's a middleware that checks for an API key on every request:

import { Hono } from 'hono'

const app = new Hono()

// Custom middleware
app.use('/api/*', async (c, next) => {
  const apiKey = c.req.header('X-API-Key')

  if (!apiKey || apiKey !== process.env.API_KEY) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  // Call next() to continue to the route handler
  await next()
})

app.get('/api/data', (c) => {
  return c.json({ secret: 'data' })
})

The pattern is the same as Express middleware — run some logic, optionally call next() to pass control along. The difference is the async/await syntax throughout and the c context object instead of req/res.

Route grouping

Hono lets you group routes with a base path, which keeps larger APIs organized:

import { Hono } from 'hono'

const app = new Hono()

// Create a sub-router for /api/v1/tasks
const tasks = new Hono()

tasks.get('/', (c) => c.json({ tasks: [] }))
tasks.post('/', async (c) => {
  const body = await c.req.json()
  return c.json({ created: body }, 201)
})
tasks.delete('/:id', (c) => {
  return c.json({ deleted: c.req.param('id') })
})

// Mount the sub-router
app.route('/api/v1/tasks', tasks)

export default app

This pattern — create a Hono instance, define routes on it, mount it with app.route() — is how you structure a real API across multiple files without everything getting tangled together.

Request validation with Zod

Hono has a first-class validator middleware that works with Zod, the TypeScript validation library AI tools almost always use:

import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'

const app = new Hono()

const createTaskSchema = z.object({
  title: z.string().min(1).max(200),
  priority: z.enum(['low', 'medium', 'high']).default('medium')
})

app.post(
  '/tasks',
  zValidator('json', createTaskSchema),
  (c) => {
    // TypeScript knows exactly what shape the body is here
    const body = c.req.valid('json')
    // body.title is string, body.priority is 'low' | 'medium' | 'high'
    return c.json({ task: { id: '1', ...body } }, 201)
  }
)

This is one of the places Hono really shines. The zValidator middleware validates the request body against your Zod schema and automatically returns a 400 error with details if it doesn't match. Your route handler only runs if the data is valid — and TypeScript knows the exact shape of c.req.valid('json'). No manual type casting, no runtime surprises.

Deploying to Cloudflare Workers

Here's what makes Hono's portability concrete. To deploy the exact same application to Cloudflare Workers instead of Node.js, your main entry file looks like this:

// For Cloudflare Workers — src/index.ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => c.json({ message: 'Hello from the edge!' }))

// Cloudflare Workers uses this export format
export default app

That's the same code. The export default app at the end is what Cloudflare Workers expects. For Node.js you'd add:

// For Node.js — add this at the bottom
import { serve } from '@hono/node-server'
serve({ fetch: app.fetch, port: 3000 })

Two lines to switch runtimes. Your routes, middleware, validation — all of it stays exactly the same. This is what "runs everywhere" actually means in practice.

When to Use Hono vs. Express vs. Next.js API Routes

This is the question that actually matters. Here's a clear framework for deciding:

Use Hono when:

  • You're starting a new backend project in 2026. There's no legacy to maintain, so take the modern choice. You'll get better TypeScript, better performance, and better edge compatibility.
  • You're deploying to Cloudflare Workers or Vercel Edge. Hono is the natural choice here. Express doesn't run on these platforms without workarounds.
  • Performance matters. If you're building an API that will handle high traffic, Hono's benchmarks are significantly better than Express, especially on Bun and edge runtimes.
  • You're using Bun as your runtime. Hono + Bun is one of the fastest combinations available for JavaScript APIs right now.
  • You want AI to generate better code for you. Hono's TypeScript-first design means AI tools produce more accurate, type-safe code with fewer runtime errors to debug.

Use Express when:

  • Your team knows Express and you're not starting from scratch. There's real value in your team being able to read and maintain the code. Don't rewrite a working Express app just to be on the newer thing.
  • You need a specific Express middleware package. Express has years of community packages. If you depend on something like express-rate-limit, passport.js, or specific auth strategies, check whether Hono equivalents exist first.
  • You're following a course or tutorial. Most backend tutorials still use Express. If you're learning from a specific resource, stay on what it teaches and switch to Hono when you're building your own thing.

Use Next.js API routes when:

  • Your backend and frontend are the same app. If you're building a Next.js app and need some server-side logic, just use Next.js route handlers (app/api/). You don't need a separate server.
  • You want one deployment. Next.js lets you ship your entire app — frontend and backend — as one thing. Hono is a separate service. Two deployments to manage.
  • You're already deep in the React/Next.js ecosystem. Server components, server actions, and the App Router can do a lot of what you'd otherwise reach for a backend framework for.

The most common pattern in 2026: use Next.js for your user-facing web app and Hono for a separate API service that mobile apps, internal tools, or third parties also need to call. When multiple different clients need the same data API, that API deserves to be its own service — and Hono is a great choice for building it.

Prompt that produces a well-structured Hono project:

"Create a Hono REST API for a task app with TypeScript. Use Zod for request validation. Structure it with a separate routes file for tasks. Include CORS middleware. Target Cloudflare Workers as the deployment platform."

The Hono Ecosystem: What Comes With It

Hono ships with more built-in capabilities than Express does out of the box. Here's what you get without installing extra packages:

Built-in middleware. Hono ships with production-ready middleware for the most common needs: CORS, logging, compression, Bearer auth, JWT authentication, rate limiting, static file serving, and more. In Express land, each of these is a separate npm package with its own versioning and maintenance concerns.

JSX rendering. Hono can render JSX server-side, without React. If you need server-rendered HTML — for emails, lightweight pages, or API responses that include markup — you can write JSX directly in your Hono handlers. This is unusual for a backend framework and surprisingly useful.

RPC client. This is Hono's most ambitious feature. You can export your API's type definitions and use them from a client-side TypeScript file, getting end-to-end type safety without writing a separate TypeScript types file. It's similar to what tRPC does. If you're building a TypeScript frontend that calls a Hono backend, this gives you autocomplete on every API call.

// server.ts
import { Hono } from 'hono'

const app = new Hono()
  .get('/tasks', (c) => c.json({ tasks: [] }))
  .post('/tasks', async (c) => {
    const body = await c.req.json()
    return c.json({ task: body })
  })

export type AppType = typeof app
export default app
// client.ts — your frontend code
import { hc } from 'hono/client'
import type { AppType } from './server'

const client = hc<AppType>('http://localhost:3000')

// TypeScript knows exactly what this returns
const response = await client.tasks.$get()
const data = await response.json()
// data.tasks is correctly typed

That's full type safety from your API handler all the way to your frontend fetch call, without a code generation step or a separate types package. When AI generates code using this pattern, the AI can verify its own output against the types — a meaningful quality improvement.

Common Patterns You'll See AI Generate

When you're working with AI tools and they produce Hono code, here are the patterns you'll see most often — and what they do:

Error handling middleware. A global error handler that catches any unhandled errors in your routes:

app.onError((err, c) => {
  console.error('Unhandled error:', err)
  return c.json({ error: 'Internal server error' }, 500)
})

app.notFound((c) => {
  return c.json({ error: 'Route not found' }, 404)
})

Environment variables. On Cloudflare Workers, environment variables are accessible through the context object's env:

// Cloudflare Workers env bindings
app.get('/secret', (c) => {
  const apiKey = c.env.API_KEY  // typed from your wrangler.toml bindings
  return c.json({ authorized: apiKey === 'expected' })
})

Chained route definitions. Hono supports chaining routes for the same path:

app
  .get('/users', listUsers)
  .post('/users', createUser)
  .get('/users/:id', getUser)
  .put('/users/:id', updateUser)
  .delete('/users/:id', deleteUser)

This reads cleanly as a table of contents for your API — which is one reason AI-generated Hono code tends to be well-organized.

What to Learn Next

Now that you know what Hono is, here are the best places to go deeper:

  • What Is Express? — Understanding Express gives you the foundation Hono builds on. Most concepts transfer directly, and Express tutorials are still the richest resource for backend patterns.
  • What Is Middleware? — Middleware is the mechanism that powers most of what makes web frameworks useful. Understanding it deeply helps you design better APIs in any framework.
  • What Is a REST API? — Before you can build a good REST API in Hono, knowing what REST means — and what makes an API RESTful versus just a collection of endpoints — is worth the time.

If you want to go hands-on with Hono specifically, the official Hono documentation is excellent and has setup guides for every runtime. The Cloudflare Workers quickstart is the fastest path to a deployed Hono API — you can have something live in under 10 minutes.

Frequently Asked Questions

What is Hono and why is it better than Express?

Hono is a lightweight web framework for JavaScript and TypeScript that runs on any JavaScript runtime — Cloudflare Workers, Vercel Edge, Deno, Bun, and Node.js. It's not necessarily "better" than Express in all cases, but it has significant advantages for modern projects: it's TypeScript-first with full type safety, it's dramatically faster on edge runtimes, and it works in environments where Express cannot run. Express still has a larger ecosystem and more community resources. Hono wins when you care about edge deployment and TypeScript ergonomics. Express wins when you need deep ecosystem support and maximum hiring familiarity.

Can I use Hono with Node.js, or does it only work on edge runtimes?

Hono works on Node.js too. The "runs everywhere" claim is real — the same Hono app code can run on Cloudflare Workers, Vercel Edge Functions, Deno, Bun, and standard Node.js. You swap out the server adapter (a few lines at the bottom of your entry file) and the core application code stays the same. This makes Hono a good choice even if you're not sure where you'll deploy yet, because you're not locked in.

Is Hono good for beginners or is it too advanced?

Hono is quite beginner-friendly for TypeScript users. The API is intentionally similar to Express — you have routes, middleware, and request/response objects that work the same way conceptually. If you've seen Express tutorials, Hono will feel familiar fast. The main difference is that Hono gives you TypeScript autocomplete and type errors from the start, which actually helps beginners catch mistakes earlier. The main learning curve is understanding why TypeScript types matter, not learning a complicated framework.

Why do AI tools like Claude and Cursor suggest Hono instead of Express?

AI coding tools recommend Hono for new projects because it aligns with patterns that produce fewer bugs and deployment headaches in 2025–2026. Hono is TypeScript-first, which means the AI can generate more accurate, type-safe code. It runs on edge runtimes that are increasingly the default deployment target for Vercel and Cloudflare. It has a clean, consistent API that produces more predictable AI-generated code. Express still works fine and the AI knows it well, but for greenfield projects with modern deployment targets, Hono is the more forward-looking suggestion.

When should I use Hono vs Next.js API routes?

Use Next.js API routes when your backend and frontend are tightly coupled and you want everything in one project — Next.js gives you file-based routing, server components, and a unified deploy. Use Hono when your backend needs to be a standalone service that multiple frontends or clients will call, when you need more control over request handling and middleware, or when you need maximum performance on edge runtimes. A common pattern: use Next.js for your main web app and Hono for a separate, dedicated API service.