What Hono is
Hono is a small, fast web framework for servers written in JavaScript and TypeScript. It maps addresses to functions, parses request data and helps you send a response: text, JSON or HTML. This course targets Hono 4 and TypeScript, with Node.js 22 or newer as the main platform.
Web standards
Hono's main feature is that it is built on web standards. A request is a Request object and a response is a Response object. These are the same classes fetch() uses in the browser; they are defined by a standard and exist in every modern environment.
All of Hono comes down to one function: it takes a Request and returns a Response.
// src/index.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello, Hono!'))
// app.fetch is a function of the form (request) => response
const res = await app.fetch(new Request('http://localhost/'))
console.log(await res.text()) // Hello, Hono!Here the app is called directly, without a server: a request goes in and a response comes back. This is exactly how every platform calls it.
Runtimes
A runtime is a program that executes JavaScript on the server. It used to be almost always Node.js; now there are several, and Hono runs on all of them:
| Runtime | How Hono is started |
|---|---|
| Node.js | through the @hono/node-server package |
| Bun | Bun's built-in server calls app.fetch |
| Deno | Deno.serve(app.fetch) |
| Cloudflare Workers | the platform calls app.fetch itself |
The route code stays the same. Only the file that starts the server changes. The course uses Node.js; the deployment lesson covers the other platforms.
What the course covers
The running example is a blog JSON API: posts and their comments, plus a few HTML pages. Along the way you will go through:
- routes, path parameters and the request body;
- middleware — shared steps for many routes;
- data validation with the zod library;
- HTML pages written in JSX;
- an SQLite database;
- sign-in with JWT and cookies;
- tests and deployment.
Hono and Express
If you know Express, a lot will look familiar: app.get(), middleware, app.use(). The difference is that a Hono handler receives a single context object c and returns the response with return instead of calling methods on a res object. Hono is also written in TypeScript from the start and knows the types of parameters, request bodies and responses.
Common mistake
Forgetting return in a handler:
// src/index.ts
app.get('/', (c) => {
c.text('Hello') // the response is created but not returned
})Hono expects the handler to return a Response. Without return the request ends with a 500 error and the terminal shows the message Context is not finalized. Write return c.text(...) or use an arrow function without curly braces.