hono-core
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHono - Ultrafast Web Framework
Hono - 超快Web框架
Overview
概述
Hono is a small, simple, and ultrafast web framework built on Web Standards. It runs on Cloudflare Workers, Deno, Bun, Node.js, and more with the same codebase. The name means "flame" in Japanese.
Key Features:
- Built on Web Standards (Request/Response/fetch)
- Multi-runtime: Cloudflare Workers, Deno, Bun, Node.js, Vercel, AWS Lambda
- Ultrafast routing with RegExpRouter
- First-class TypeScript support
- Lightweight (~14KB minified)
- Rich middleware ecosystem
Installation:
bash
undefinedHono是一个基于Web标准构建的小巧、简洁且超快的Web框架。它可以在Cloudflare Workers、Deno、Bun、Node.js等多个环境中运行,且代码库一致。其名称在日语中意为“火焰”。
核心特性:
- 基于Web标准(Request/Response/fetch)
- 多运行时支持:Cloudflare Workers、Deno、Bun、Node.js、Vercel、AWS Lambda
- 采用RegExpRouter实现超快路由
- 一等公民的TypeScript支持
- 轻量级(压缩后约14KB)
- 丰富的中间件生态系统
安装:
bash
undefinedCreate new project (recommended)
创建新项目(推荐)
npm create hono@latest my-app
npm create hono@latest my-app
Or install in existing project
或在现有项目中安装
npm install hono
npm install hono
Runtime-specific adapters
特定运行时适配器
npm install @hono/node-server # Node.js
undefinednpm install @hono/node-server # Node.js
undefinedWhen to Use This Skill
何时使用该框架
Use Hono when:
- Building APIs for edge/serverless environments (Cloudflare Workers, Vercel Edge)
- Need multi-runtime portability (same code on Bun, Deno, Node.js)
- Want TypeScript-first development with excellent type inference
- Building lightweight, high-performance APIs
- Need built-in middleware for common patterns (CORS, auth, compression)
Hono vs Other Frameworks:
- Hono: Multi-runtime, Web Standards, ultrafast, edge-optimized
- Express: Node.js only, larger ecosystem, slower
- Fastify: Node.js only, schema-based, good performance
- Elysia: Bun only, excellent performance, different API style
在以下场景选择Hono:
- 为边缘/无服务器环境(Cloudflare Workers、Vercel Edge)构建API
- 需要多运行时可移植性(同一代码在Bun、Deno、Node.js上运行)
- 希望采用TypeScript优先的开发模式,且获得出色的类型推断
- 构建轻量级、高性能API
- 需要内置中间件处理常见模式(CORS、认证、压缩)
Hono与其他框架对比:
- Hono: 多运行时、基于Web标准、超快、边缘优化
- Express: 仅支持Node.js、生态系统更庞大、速度较慢
- Fastify: 仅支持Node.js、基于Schema、性能良好
- Elysia: 仅支持Bun、性能优异、API风格不同
Core Concepts
核心概念
Creating an Application
创建应用
typescript
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Hono!'))
export default appWith TypeScript Generics (for bindings/variables):
typescript
type Bindings = {
DATABASE_URL: string
API_KEY: string
}
type Variables = {
user: { id: string; name: string }
}
const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()typescript
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Hono!'))
export default app使用TypeScript泛型(用于绑定/变量):
typescript
type Bindings = {
DATABASE_URL: string
API_KEY: string
}
type Variables = {
user: { id: string; name: string }
}
const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()The Context Object (c)
上下文对象 (c)
The context provides access to request data and response methods:
ctypescript
app.get('/users/:id', async (c) => {
// Request data
const id = c.req.param('id') // Path parameter
const query = c.req.query('sort') // Query parameter ?sort=asc
const queries = c.req.queries('tags') // Multiple: ?tags=a&tags=b
const header = c.req.header('Authorization')
const body = await c.req.json() // JSON body
const form = await c.req.formData() // Form data
// Environment (Cloudflare Workers bindings)
const db = c.env.DATABASE_URL
// Custom variables (set by middleware)
const user = c.get('user')
// Response methods
return c.text('Plain text')
return c.json({ id, name: 'User' })
return c.html('<h1>Hello</h1>')
return c.redirect('/login')
return c.notFound()
})上下文提供对请求数据和响应方法的访问:
ctypescript
app.get('/users/:id', async (c) => {
// 请求数据
const id = c.req.param('id') // 路径参数
const query = c.req.query('sort') // 查询参数 ?sort=asc
const queries = c.req.queries('tags') // 多值参数: ?tags=a&tags=b
const header = c.req.header('Authorization')
const body = await c.req.json() // JSON请求体
const form = await c.req.formData() // 表单数据
// 环境变量(Cloudflare Workers绑定)
const db = c.env.DATABASE_URL
// 自定义变量(由中间件设置)
const user = c.get('user')
// 响应方法
return c.text('Plain text')
return c.json({ id, name: 'User' })
return c.html('<h1>Hello</h1>')
return c.redirect('/login')
return c.notFound()
})Response Methods
响应方法
typescript
// Text response
c.text('Hello', 200)
// JSON response
c.json({ message: 'Success' }, 201)
c.json({ error: 'Not found' }, 404)
// HTML response
c.html('<h1>Hello</h1>')
// Redirect
c.redirect('/login') // 302 default
c.redirect('/login', 301) // Permanent redirect
// Headers
c.header('X-Custom', 'value')
c.header('Cache-Control', 'max-age=3600')
// Streaming
c.streamText(async (stream) => {
await stream.write('Hello ')
await stream.write('World!')
})
// Raw Response
return new Response('Raw', { status: 200 })typescript
// 文本响应
c.text('Hello', 200)
// JSON响应
c.json({ message: 'Success' }, 201)
c.json({ error: 'Not found' }, 404)
// HTML响应
c.html('<h1>Hello</h1>')
// 重定向
c.redirect('/login') // 默认302临时重定向
c.redirect('/login', 301) // 301永久重定向
// 设置响应头
c.header('X-Custom', 'value')
c.header('Cache-Control', 'max-age=3600')
// 流式响应
c.streamText(async (stream) => {
await stream.write('Hello ')
await stream.write('World!')
})
// 原始Response对象
return new Response('Raw', { status: 200 })Routing Patterns
路由模式
Basic Routing
基础路由
typescript
const app = new Hono()
// HTTP methods
app.get('/users', getUsers)
app.post('/users', createUser)
app.put('/users/:id', updateUser)
app.delete('/users/:id', deleteUser)
app.patch('/users/:id', patchUser)
// All methods
app.all('/webhook', handleWebhook)
// Custom methods
app.on('PURGE', '/cache', purgeCache)
app.on(['GET', 'POST'], '/form', handleForm)typescript
const app = new Hono()
// HTTP方法
app.get('/users', getUsers)
app.post('/users', createUser)
app.put('/users/:id', updateUser)
app.delete('/users/:id', deleteUser)
app.patch('/users/:id', patchUser)
// 匹配所有HTTP方法
app.all('/webhook', handleWebhook)
// 自定义HTTP方法
app.on('PURGE', '/cache', purgeCache)
app.on(['GET', 'POST'], '/form', handleForm)Path Parameters
路径参数
typescript
// Single parameter
app.get('/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ id })
})
// Multiple parameters
app.get('/posts/:postId/comments/:commentId', (c) => {
const { postId, commentId } = c.req.param()
return c.json({ postId, commentId })
})
// Optional parameter
app.get('/api/animal/:type?', (c) => {
const type = c.req.param('type') || 'all'
return c.json({ type })
})
// Regex validation
app.get('/posts/:id{[0-9]+}', (c) => {
const id = c.req.param('id') // Only numeric IDs
return c.json({ id })
})
// Wildcards
app.get('/files/*', (c) => {
const path = c.req.param('*') // Everything after /files/
return c.text(`File: ${path}`)
})typescript
// 单个参数
app.get('/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ id })
})
// 多个参数
app.get('/posts/:postId/comments/:commentId', (c) => {
const { postId, commentId } = c.req.param()
return c.json({ postId, commentId })
})
// 可选参数
app.get('/api/animal/:type?', (c) => {
const type = c.req.param('type') || 'all'
return c.json({ type })
})
// 正则验证
app.get('/posts/:id{[0-9]+}', (c) => {
const id = c.req.param('id') // 仅匹配数字ID
return c.json({ id })
})
// 通配符
app.get('/files/*', (c) => {
const path = c.req.param('*') // /files/之后的所有内容
return c.text(`File: ${path}`)
})Route Grouping
路由分组
typescript
// Using app.route()
const api = new Hono()
api.get('/users', getUsers)
api.get('/posts', getPosts)
const app = new Hono()
app.route('/api/v1', api) // /api/v1/users, /api/v1/posts
// Using basePath()
const v2 = new Hono().basePath('/api/v2')
v2.get('/users', getUsers) // /api/v2/users
// Chaining
app
.get('/a', handlerA)
.post('/b', handlerB)
.delete('/c', handlerC)typescript
// 使用app.route()
const api = new Hono()
api.get('/users', getUsers)
api.get('/posts', getPosts)
const app = new Hono()
app.route('/api/v1', api) // 对应路径 /api/v1/users, /api/v1/posts
// 使用basePath()
const v2 = new Hono().basePath('/api/v2')
v2.get('/users', getUsers) // 对应路径 /api/v2/users
// 链式调用
app
.get('/a', handlerA)
.post('/b', handlerB)
.delete('/c', handlerC)Route Organization (Multi-File)
路由组织(多文件)
typescript
// routes/users.ts
import { Hono } from 'hono'
const users = new Hono()
users.get('/', async (c) => {
return c.json({ users: [] })
})
users.post('/', async (c) => {
const body = await c.req.json()
return c.json({ created: body }, 201)
})
users.get('/:id', async (c) => {
const id = c.req.param('id')
return c.json({ id })
})
export default users
// app.ts
import { Hono } from 'hono'
import users from './routes/users'
import posts from './routes/posts'
const app = new Hono()
app.route('/users', users)
app.route('/posts', posts)
export default apptypescript
// routes/users.ts
import { Hono } from 'hono'
const users = new Hono()
users.get('/', async (c) => {
return c.json({ users: [] })
})
users.post('/', async (c) => {
const body = await c.req.json()
return c.json({ created: body }, 201)
})
users.get('/:id', async (c) => {
const id = c.req.param('id')
return c.json({ id })
})
export default users
// app.ts
import { Hono } from 'hono'
import users from './routes/users'
import posts from './routes/posts'
const app = new Hono()
app.route('/users', users)
app.route('/posts', posts)
export default appHandler Patterns
处理器模式
Inline Handlers
内联处理器
typescript
// Simple handler
app.get('/hello', (c) => c.text('Hello!'))
// Async handler
app.get('/users', async (c) => {
const users = await fetchUsers()
return c.json({ users })
})
// Multiple handlers (middleware chain)
app.get('/admin', authenticate, authorize, (c) => {
return c.json({ admin: true })
})typescript
// 简单处理器
app.get('/hello', (c) => c.text('Hello!'))
// 异步处理器
app.get('/users', async (c) => {
const users = await fetchUsers()
return c.json({ users })
})
// 多个处理器(中间件链)
app.get('/admin', authenticate, authorize, (c) => {
return c.json({ admin: true })
})Using Factory for Type-Safe Handlers
使用工厂创建类型安全的处理器
typescript
import { createFactory } from 'hono/factory'
const factory = createFactory<{ Bindings: Bindings }>()
// Create typed handler
const getUser = factory.createHandlers(async (c) => {
const id = c.req.param('id')
const db = c.env.DATABASE_URL // Typed!
return c.json({ id })
})
app.get('/users/:id', ...getUser)typescript
import { createFactory } from 'hono/factory'
const factory = createFactory<{ Bindings: Bindings }>()
// 创建类型化处理器
const getUser = factory.createHandlers(async (c) => {
const id = c.req.param('id')
const db = c.env.DATABASE_URL // 已类型化!
return c.json({ id })
})
app.get('/users/:id', ...getUser)Error Handling
错误处理
Built-in Error Handling
内置错误处理
typescript
import { HTTPException } from 'hono/http-exception'
app.get('/users/:id', async (c) => {
const user = await findUser(c.req.param('id'))
if (!user) {
throw new HTTPException(404, { message: 'User not found' })
}
return c.json(user)
})
// Global error handler
app.onError((err, c) => {
console.error(`${err}`)
if (err instanceof HTTPException) {
return err.getResponse()
}
return c.json({ error: 'Internal Server Error' }, 500)
})
// Not found handler
app.notFound((c) => {
return c.json({ error: 'Route not found' }, 404)
})typescript
import { HTTPException } from 'hono/http-exception'
app.get('/users/:id', async (c) => {
const user = await findUser(c.req.param('id'))
if (!user) {
throw new HTTPException(404, { message: 'User not found' })
}
return c.json(user)
})
// 全局错误处理器
app.onError((err, c) => {
console.error(`${err}`)
if (err instanceof HTTPException) {
return err.getResponse()
}
return c.json({ error: 'Internal Server Error' }, 500)
})
// 404未找到处理器
app.notFound((c) => {
return c.json({ error: 'Route not found' }, 404)
})Custom Error Classes
自定义错误类
typescript
class ValidationError extends HTTPException {
constructor(errors: string[]) {
super(400, {
message: 'Validation failed',
cause: errors
})
}
}
class AuthenticationError extends HTTPException {
constructor() {
super(401, { message: 'Authentication required' })
}
}typescript
class ValidationError extends HTTPException {
constructor(errors: string[]) {
super(400, {
message: 'Validation failed',
cause: errors
})
}
}
class AuthenticationError extends HTTPException {
constructor() {
super(401, { message: 'Authentication required' })
}
}Runtime-Specific Exports
特定运行时导出
Cloudflare Workers
Cloudflare Workers
typescript
// src/index.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Cloudflare!'))
export default apptypescript
// src/index.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Cloudflare!'))
export default appNode.js
Node.js
typescript
// src/index.ts
import { serve } from '@hono/node-server'
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Node!'))
serve({
fetch: app.fetch,
port: 3000
})typescript
// src/index.ts
import { serve } from '@hono/node-server'
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Node!'))
serve({
fetch: app.fetch,
port: 3000
})Bun
Bun
typescript
// src/index.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Bun!'))
export default {
port: 3000,
fetch: app.fetch
}typescript
// src/index.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Bun!'))
export default {
port: 3000,
fetch: app.fetch
}Deno
Deno
typescript
// main.ts
import { Hono } from 'npm:hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Deno!'))
Deno.serve(app.fetch)typescript
// main.ts
import { Hono } from 'npm:hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Deno!'))
Deno.serve(app.fetch)Best Practices
最佳实践
Write Handlers Inline (Not Controllers)
编写内联处理器(而非控制器风格)
typescript
// CORRECT: Inline handlers with proper type inference
app.get('/users/:id', async (c) => {
const id = c.req.param('id') // Type: string
return c.json({ id })
})
// AVOID: Controller-style (loses type inference)
class UserController {
getUser(c: Context) {
const id = c.req.param('id') // Type: string | undefined
return c.json({ id })
}
}typescript
// 推荐:内联处理器,具备完整类型推断
app.get('/users/:id', async (c) => {
const id = c.req.param('id') // 类型: string
return c.json({ id })
})
// 避免:控制器风格(丢失类型推断)
class UserController {
getUser(c: Context) {
const id = c.req.param('id') // 类型: string | undefined
return c.json({ id })
}
}Use Modular Routes
使用模块化路由
typescript
// CORRECT: Split routes by domain
// routes/users.ts
export const users = new Hono()
.get('/', listUsers)
.post('/', createUser)
.get('/:id', getUser)
// app.ts
app.route('/users', users)typescript
// 推荐:按领域拆分路由
// routes/users.ts
export const users = new Hono()
.get('/', listUsers)
.post('/', createUser)
.get('/:id', getUser)
// app.ts
app.route('/users', users)Type Everything
为所有内容添加类型
typescript
// Define your environment bindings
type Bindings = {
DATABASE_URL: string
JWT_SECRET: string
MY_KV: KVNamespace
}
// Pass to Hono
const app = new Hono<{ Bindings: Bindings }>()
// Now c.env is fully typed
app.get('/', (c) => {
const url = c.env.DATABASE_URL // string
const kv = c.env.MY_KV // KVNamespace
})typescript
// 定义环境绑定类型
type Bindings = {
DATABASE_URL: string
JWT_SECRET: string
MY_KV: KVNamespace
}
// 传递给Hono
const app = new Hono<{ Bindings: Bindings }>()
// 现在c.env具备完整类型
app.get('/', (c) => {
const url = c.env.DATABASE_URL // string类型
const kv = c.env.MY_KV // KVNamespace类型
})Quick Reference
快速参考
Common Context Methods
常用上下文方法
| Method | Description | Example |
|---|---|---|
| Get path parameter | |
| Get query parameter | |
| Get request header | |
| Parse JSON body | |
| Parse form data | |
| Text response | |
| JSON response | |
| HTML response | |
| Redirect | |
| Set response header | |
| Set context variable | |
| Get context variable | |
| Environment bindings | |
| 方法 | 描述 | 示例 |
|---|---|---|
| 获取路径参数 | |
| 获取查询参数 | |
| 获取请求头 | |
| 解析JSON请求体 | |
| 解析表单数据 | |
| 返回文本响应 | |
| 返回JSON响应 | |
| 返回HTML响应 | |
| 重定向 | |
| 设置响应头 | |
| 设置上下文变量 | |
| 获取上下文变量 | |
| 环境绑定 | |
HTTP Methods
HTTP方法
typescript
app.get(path, ...handlers)
app.post(path, ...handlers)
app.put(path, ...handlers)
app.delete(path, ...handlers)
app.patch(path, ...handlers)
app.options(path, ...handlers)
app.head(path, ...handlers)
app.all(path, ...handlers)
app.on(method, path, ...handlers)typescript
app.get(path, ...handlers)
app.post(path, ...handlers)
app.put(path, ...handlers)
app.delete(path, ...handlers)
app.patch(path, ...handlers)
app.options(path, ...handlers)
app.head(path, ...handlers)
app.all(path, ...handlers)
app.on(method, path, ...handlers)Related Skills
相关技能
- hono-middleware - Middleware patterns and composition
- hono-validation - Request validation with Zod
- hono-rpc - Type-safe RPC client
- hono-testing - Testing patterns
- hono-jsx - Server-side JSX rendering
- hono-cloudflare - Cloudflare Workers deployment
Version: Hono 4.x
Last Updated: January 2025
License: MIT
- hono-middleware - 中间件模式与组合
- hono-validation - 使用Zod进行请求验证
- hono-rpc - 类型安全的RPC客户端
- hono-testing - 测试模式
- hono-jsx - 服务端JSX渲染
- hono-cloudflare - Cloudflare Workers部署
版本: Hono 4.x
最后更新: 2025年1月
许可证: MIT