Hono.js
Introduction
This document provides an overview of Hono.js, a small, simple and ultrafast web framework. It works on any JavaScript runtime, including Cloudflare Workers.
Features:
- Ultrafast - The router
RegExpRouteris really fast. Not using linear loops. Fast - Lightweight - The
hono/tinypreset in under 14kB. Hono has zero dependencies and uses only the Web Standards. - Multi-runtime - Works on Cloudflare Workers, AWS Lambda etc. The same code runs on all platforms.
- Batteries Included - Hono has built-in middleware, custom middleware, third-party middleware and helpers.
- Delightful DX - Super clean APIs. First-class TypeScript support.
- Multiple routers -
RegExpRouteris the fastest router in the JavaScript world. It matches the route using a single large Regex created before dispatch. WithSmartRouterit supports all route patterns.LinearRouterregisters the routes very quickly, so it's suitable for an environment that initializes applications every time.PatternRoutersimply adds and matches the pattern, making it small.
Use-cases
- Building Web APIs
- Proxy of backend servers
- Front of CDN
- Edge application
- Full-stack application
Middleware & Helpers
- basic authentication
- bearer authentication
- body limit
- cache
- compress
- context storage
- cookie
- CORS
- ETag
- JSX
- JWT Authentication
- Logger
- Pretty JSON
- Secure Headers
- SSG
- Streaming
Routers
The routers are the most important features for Hono. Hono.js has five routers.
RegExpRouter
The RegExpRouter is the fastest router in the JavaScript world. It turns the route pattern into "one large regular expression". Then it can get the result with one-time matching. This works faster than methods that use tree-based algorithms such as radix-tree in most cases.
TrieRouter
The TrieRouter is the router using the Trie-tree algorithm. It does not use linear loops as same as RegExpRouter. The router is not as fast as the RegExpRouter, but it is much faster than the Express router. TrieRouter supports all patterns though RegExpRouter does not.
SmartRouter
RegExpRouter does not support all routing patterns. Therefore, it's usually used in combination with another router that does support all patterns.
SmartRouter will select the best router by inferring from the registered routers. Hono uses SmartRouter and the two routers by default.
// Inside the core of Hono.
readonly defaultRouter: Router = new SmartRouter({
routers: [new RegExpRouter(), new TrieRouter()],
})TIP
When the application starts, SmartRouter detects the fastest router based on routing and continues to use it.
LinearRouter
RegExpRouter is fast, but the route registration phase can be slightly slow. So, it's not suitable for an environment that initializes with every request.
LinearRouter is optimized for "one shot" situations. Route registration is significantly faster than RegExpRouter because it adds the route without compiling strings, using a linear approach.
TIP
For situations like Fastly Compute, it is better to use LinearRouter with the hono/quick preset.
PatternRouter
PatternRouter is the smallest router among Hono's routers. While Hono is already compact, if you need to make it even smaller for an environment with limited resources you can use PatternRouter.
TIP
An application using only PatternRouter is under 15KB in size.
Middleware
We call the primitive that returns Response as "Handler". "Middleware" is executed before and after the Handler and handles the Request and Response.
Request -> MA -> MB -> MC -> Handler returns Response -> MC -> MB -> MA -> Response
For example, we can write the middleware to add the X-Response-Time header as follows:
app.use(async (c, next) => {
const start = Date.now()
await next()
const end = Date.now()
c.res.headers.set('X-Response-Time', `${end - start}`)
})Hono Stacks
Hono makes easy things easy and hard things easy. It is suitable for not just only returning JSON. But it is also great for building the full-stack application including REST API servers and the client.
RPC
Hono's RPC feature allows you to share API specs with litthe change to your code. The client generated by hc will read the spec and access the endpoint type-safety.
The following libraries make it possible:
- Hono - API Server
- Zod - Validator
- Zod Validator Middleware - Middleware for validation
- hc - HTTP Client
Writing API
Endpoint that receives a GET request and returns JSON
First, write an endpoint that receives a GET request and returns JSON.
import { Hono } from 'hono'
const app = new Hono()
app.get('/hello', (c) => {
return c.json({
message: `Hello!`,
})
})Validation with Zod
Validate with Zod to receive the value of the query parameter.
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const app = new Hono()
app.get(
'/hello',
zValidator(
'query',
z.object({
name: z.string(),
})
),
(c) => {
const { name } = c.req.valid('query')
return c.json({
message: `Hello! ${name}`,
})
}
)Sharing the Types
To emit an endpoint specification, export its type.
const route = app.get(
'/hello',
zValidator(
'query',
z.object({
name: z.string(),
})
),
(c) => {
const { name } = c.req.valid('query')
return c.json({
message: `Hello! ${name}`,
})
}
)
export type AppType = typeof route