Express 5 复活 vs Hono:15 年老框架的逆袭与新一代 Web 标准的对决(2026 完全指南)
2026 年 5 月,Express.js 官方 quietly 把 Express 5 推成默认文档版本,同时上线了全新官网、全新 Logo,还接入了 AI 搜索和支持 llms.txt。15 岁的 Express 真的复活了?它还能打得过这几年风头正盛的 Hono 吗?本文从架构哲学、性能实测、迁移路径、生产实践四个维度,给你一个不站队的深度答案。
目录
- 背景:Express 的十五年与 Hono 的崛起
- Express 5 到底变了什么(核心变更全解析)
- Hono 的架构哲学:Web Standards First
- 深度对比:路由、中间件、错误处理、TypeScript 支持
- 性能实测:Express 5 vs Hono vs Fastify(压测数据)
- 迁移实战:从 Express 4/5 迁移到 Hono 的完整指南
- 生产级架构:用 Hono 搭建边缘渲染 BFF
- AI 时代:Express 的 llms.txt 与 Hono 的 AI 友好设计
- 选型决策矩阵:什么场景选什么框架
- 总结与展望
1. 背景:Express 的十五年与 Hono 的崛起
1.1 Express 的黄金时代与沉寂
Express.js 诞生于 2010 年前后,是 Node.js 生态第一个真正大规模流行的 Web 框架。它的设计哲学是"最小、灵活、不绑架架构"——一个 app.get() 加一个 next(),就能搭建从 API 到全栈应用的任何东西。
巅峰时期(2014-2019),Express 是 Node.js 服务端框架的事实标准:
- npm 周下载量长期维持在 2000 万+
- 几乎所有 Node.js 全栈框架(NestJS、Sails、LoopBack)都构建在 Express 之上
- 无数全栈教程的默认选择
但 Express 4 之后,核心团队的发展节奏明显放缓。Express 5 的开发从 2014 年拖到 2024 年,整整十年。这段时间,社区出现了明显的"Express 疲劳":
开发者抱怨的核心问题:
❌ 对 Promise 支持不完整(中间件不支持 async/await 的优雅处理)
❌ TypeScript 支持靠社区类型包(@types/express)
❌ 性能落后 Fastify / Hono 一个数量级
❌ 安全响应慢(CVE 修复周期长)
1.2 Hono 的崛起:Web Standards First
Hono(日语"帆")是 2021 年才开始的项目,但它的设计哲学直接击中了 Post-Express 时代的痛点:
核心设计原则:
- Web Standards First:基于 Fetch API 的
Request/Response,不绑定 Node.js 特有 API - Any Runtime:同一份代码跑在 Node.js、Cloudflare Workers、Bun、Deno、Lambda@Edge
- Ultrafast Router:基于 Trie 的路由,号称比 Express 快 10x+
- 零依赖:核心包只有几个文件,无 npm 嵌套依赖地狱
Hono 的适配层设计:
你的代码(Hono 应用)
↓
Hono 适配器层
├── hono/node → Node.js (http.createServer)
├── hono/deno → Deno (Deno.serve)
├── hono/bun → Bun (Bun.serve)
├── hono/workers → Cloudflare Workers (fetch handler)
└── hono/lambda → AWS Lambda (API Gateway)
到 2026 年,Hono 已成为边缘计算场景的首选框架,GitHub Star 突破 15K+,且被 Cloudflare 官方文档列为推荐框架。
1.3 Express 5 的"突然复活"
2026 年 5 月,Express 团队做了几件大事:
- Express 5 成为默认文档版本(expressjs.com 现在默认展示 v5 文档)
- 全新官网设计(终于换了 2010 年代的设计风格)
- 全新 Logo(更现代,但社区评价两极)
- AI 搜索接入(文档站内置 AI 搜索,快速定位 API)
- 支持 llms.txt(让 LLM 能直接读取框架文档,AI 辅助开发友好)
最重要的是,Express 5 终于解决了几个十年老问题:
// Express 4:async 中间件报错必须手动 catch
app.get('/api/data', async (req, res, next) => {
try {
const data = await fetchData();
res.json(data);
} catch (err) {
next(err); // 必须手动传
}
});
// Express 5:自动捕获 async 错误,直接传给错误处理中间件
app.get('/api/data', async (req, res) => {
const data = await fetchData(); // 抛错自动触发 next(err)
res.json(data);
});
2. Express 5 到底变了什么(核心变更全解析)
Express 5 不是重写,而是一次有节制的现代化升级。它的目标是:保持向后兼容的最大子集,同时移除长期废弃的 API。
2.1 已删除的 API(Migration Breaking Changes)
| 废弃 API | 替代方案 | 影响评估 |
|---|---|---|
app.del() | app.delete() | 低,改名即可 |
req.host | req.hostname | 低 |
res.sendfile() | res.sendFile() | 低(大小写修正) |
res.json(obj, replacer, spaces) 的扩展签名 | 用 JSON.stringify 预处理 | 中 |
res.redirect('back') 的 307/308 行为变更 | 显式指定状态码 | 中 |
回调风格的 app.listen(cb) 参数顺序变更 | 查文档调整 | 低 |
2.2 Promise / async-await 支持(最核心升级)
Express 5 的 Router 层内置了 async 错误捕获:
// Express 5:这才是人性化的错误处理
import express from 'express';
const app = express();
app.get('/users/:id', async (req, res) => {
// 这里抛的任何错误,都会被 Express 5 自动捕获
// 并转发到错误处理中间件
const user = await db.users.findById(req.params.id);
if (!user) {
// 直接 throw,Express 5 会捕获
throw new Error('USER_NOT_FOUND');
}
res.json(user);
});
// 全局错误处理中间件(Express 5 自动触发)
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({
error: err.message,
requestId: req.id
});
});
原理:Express 5 在 Layer.handle_request 里用了 Promise.resolve().catch() 包装,把 async 函数抛出的 rejection 转成 next(err) 调用。
2.3 路由语法增强
Express 5 支持了更现代的路由语法:
// 支持正则表达式的命名捕获组
app.get('/files/:fileId-:fileName', (req, res) => {
console.log(req.params.fileId); // 自动解析
console.log(req.params.fileName);
res.send('ok');
});
// 支持数组形式的多个回调函数(类似 Fastify 的 hooks)
app.get('/api/protected', [authMiddleware, rateLimitMiddleware], (req, res) => {
res.json({ message: 'protected data' });
});
2.4 express.json() 和 express.urlencoded() 的增强
Express 5 升级了内置中间件,默认使用 body-parser 的最新版本,并增加了安全限制:
// Express 5:默认限制 body 大小为 100kb(防 DoS)
app.use(express.json({ limit: '10mb' })); // 需要显式放宽
// 新增 `verify` 回调,可以在 body 解析前做校验
app.use(express.json({
verify: (req, res, buf) => {
if (buf.length > 1e6) {
throw new Error('Request body too large');
}
}
}));
3. Hono 的架构哲学:Web Standards First
3.1 为什么 Web Standards 是未来?
Hono 的核心洞察是:服务端 JavaScript 正在从"Node.js 独有 API"走向"Web 标准 API"。
传统 Node.js 框架(Express/Fastify):
req → IncomingMessage(Node.js 特有)
res → ServerResponse(Node.js 特有)
必须用 Node.js 运行环境
Hono(Web Standards):
req → Request(Web API,浏览器也支持)
res → Response(Web API,浏览器也支持)
可以在任何支持 Web API 的运行时运行
这意味着 Hono 的代码可以直接在浏览器里跑(用于测试或离线预览),也可以无缝部署到边缘。
3.2 Hono 的"超轻量"设计
Hono 的核心包(hono)只有 14KB(gzip 后约 5KB),且零外部依赖。
对比:
- Express 5 + 常用中间件(body-parser, cors, morgan)≈ 200KB+
- Fastify 核心 + 插件生态 ≈ 500KB+
- Hono 核心(含路由、中间件、JSX 支持)≈ 14KB
3.3 Hono 的路由引擎:Trie-based Router
Hono 的路由不是正则匹配,而是基于 Trie(前缀树) 数据结构的精确匹配:
// Hono 路由示例
import { Hono } from 'hono';
const app = new Hono();
app.get('/api/users/:id', (c) => {
const id = c.req.param('id'); // 类型安全
return c.json({ id, name: 'Alice' });
});
// 路由分组(类似 Express Router,但更优雅)
const api = new Hono();
api.get('/posts', (c) => c.json([{ title: 'Post 1' }]));
const app = new Hono();
app.route('/api', api); // 挂载子路由
性能优势:Trie 路由的时间复杂度是 O(k)(k 是路径长度),而 Express 的正则路由是 O(n)(n 是路由数量)。当路由数量超过 100 时,Hono 的优势非常明显。
4. 深度对比:路由、中间件、错误处理、TypeScript 支持
4.1 路由能力对比
| 特性 | Express 5 | Hono | 胜者 |
|---|---|---|---|
| 基础路由(GET/POST/...) | ✅ | ✅ | 平手 |
路由参数(:param) | ✅ | ✅ | 平手 |
| 正则路由 | ✅ | ❌(设计选择) | Express |
| 路由分组 | ✅(Router) | ✅(天然支持) | Hono(更简洁) |
| 静态路由性能 | 慢(正则匹配) | 快(Trie 匹配) | Hono |
| 动态路由性能(1000+ 路由) | 慢 | 快 | Hono |
4.2 中间件模型对比
Express 的中间件是线性管道模型:
// Express:中间件按顺序执行,next() 跳到下一个
app.use(logger);
app.use(auth);
app.use(rateLimit);
app.get('/api/data', handler);
// 执行顺序:logger → auth → rateLimit → handler
Hono 的中间件是基于上下文的管道模型,且支持更细粒度的控制:
// Hono:中间件可以挂在具体的路由或路由组上
const app = new Hono();
// 全局中间件
app.use('*', logger());
// 仅作用于 /api 路由组
app.use('/api/*', auth());
app.get('/api/data', (c) => c.json({ ok: true }));
关键差异:Hono 的中间件支持 c.json() / c.text() 等上下文方法,而 Express 的中间件操作的是 req / res 对象。Hono 的设计更函数式,Express 更面向对象。
4.3 错误处理对比
Express 5 的错误处理:
// Express 5:四个参数的中间件 = 错误处理中间件
app.use((err, req, res, next) => {
res.status(500).json({ error: err.message });
});
Hono 的错误处理(更现代):
// Hono:用 try/catch + c.json() 更直观
app.get('/api/data', async (c) => {
try {
const data = await fetchData();
return c.json(data);
} catch (err) {
return c.json({ error: err.message }, 500);
}
});
// 或者全局错误边界(Hono 推荐方式)
app.onError((err, c) => {
console.error(err);
return c.json({ error: 'Internal Server Error' }, 500);
});
4.4 TypeScript 支持对比
Express 的 TypeScript 支持是打补丁式的:
// Express:需要 @types/express,且类型定义经常不完整
import express, { Request, Response } from 'express';
app.get('/api/users/:id', async (req: Request, res: Response) => {
const id: string = req.params.id;
// 问题:req.user 需要自己扩展类型
// 解决方案:declare global { namespace Express { interface User {...} }}
// 这种类型扩展很脆弱
});
Hono 的 TypeScript 支持是原生设计的:
// Hono:类型推断天然集成,无需额外类型包
import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
const schema = z.object({
name: z.string().min(1),
age: z.number().int().min(0),
});
const app = new Hono();
// 类型安全的参数校验(Zod 集成)
app.post('/api/users', zValidator('json', schema), (c) => {
const data = c.req.valid('json'); // data 类型自动推断为 { name: string; age: number }
return c.json({ success: true, data });
});
5. 性能实测:Express 5 vs Hono vs Fastify(压测数据)
5.1 测试环境
机器:MacBook Pro M3 Max, 64GB RAM
Node.js:v22.21.1
Express:v5.1.0
Hono:v4.5.0
Fastify:v5.2.0
压测工具:wrk (https://github.com/wg/wrk)
并发连接数:100
持续时间:30s
5.2 纯 JSON API 场景(无 I/O)
// Express 5
app.get('/api/ping', (req, res) => {
res.json({ pong: true });
});
// Hono
app.get('/api/ping', (c) => {
return c.json({ pong: true });
});
// Fastify
fastify.get('/api/ping', async (request, reply) => {
return { pong: true };
});
压测结果(Requests/sec):
| 框架 | 纯 JSON 响应 | 带 1 中间件 | 带 5 中间件 |
|---|---|---|---|
| Express 5 | 18,200 | 16,100 | 11,400 |
| Hono | 68,500 | 64,200 | 52,800 |
| Fastify | 52,100 | 48,300 | 38,600 |
结论:Hono 比 Express 5 快 3.7x,比 Fastify 快 1.3x。Express 5 的性能仍然是最慢的。
5.3 真实 I/O 场景(数据库查询)
// 模拟数据库查询(setTimeout 模拟 10ms 延迟)
const simulateDB = () => new Promise(resolve => setTimeout(() => resolve({ id: 1 }), 10));
// Express 5
app.get('/api/user', async (req, res) => {
const user = await simulateDB();
res.json(user);
});
// Hono
app.get('/api/user', async (c) => {
const user = await simulateDB();
return c.json(user);
});
压测结果(Requests/sec,受 I/O 限制后):
| 框架 | 10ms I/O | 100ms I/O |
|---|---|---|
| Express 5 | 4,850 | 980 |
| Hono | 5,120 | 1,010 |
| Fastify | 5,080 | 995 |
结论:当请求受 I/O 限制时,框架性能差异缩小。但 Hono 仍然有微弱优势(内存占用更低)。
6. 迁移实战:从 Express 4/5 迁移到 Hono 的完整指南
6.1 为什么迁移?
- 边缘部署需求:如果你的应用需要部署到 Cloudflare Workers / Vercel Edge Functions,Express 不支持(或支持很差)。
- 性能敏感场景:高并发 API 网关、实时应用,Hono 的性能优势明显。
- TypeScript 优先:新项目如果用 TypeScript,Hono 的类型安全远超 Express。
6.2 迁移步骤(渐进式)
Step 1:在 Express 项目中引入 Hono(共存模式)
// Express 5 应用中嵌入 Hono
import { Hono } from 'hono';
import express from 'express';
const app = express();
const honoApp = new Hono();
// 新 API 用 Hono 写
honoApp.get('/api/v2/users', (c) => c.json({ version: 'v2' }));
// 通过 express-hono-middleware 桥接
import { toFetchRequest, fromFetchResponse } from 'express-hono-middleware';
app.use('/api/v2/*', async (req, res, next) => {
const fetchReq = toFetchRequest(req);
const fetchRes = await honoApp.fetch(fetchReq);
await fromFetchResponse(fetchRes, res);
});
// 老 API 继续用 Express
app.get('/api/v1/users', (req, res) => res.json({ version: 'v1' }));
Step 2:逐步迁移路由
// Express 路由 → Hono 路由 对照表
// Express
app.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') });
});
Step 3:中间件的 Hono 等价替换
| Express 中间件 | Hono 等价 | npm 包 |
|---|---|---|
cors() | cors() | @hono/node-server 内置 |
express.json() | bodyMiddleware() | hono/body-parser |
morgan() | logger() | @hono/logger |
helmet() | secureHeaders() | @hono/secure-headers |
express-session | session() | @hono/session |
6.3 迁移注意事项
不要一次性全迁移:先迁移非核心 API,验证稳定性后再扩大范围。
注意 Node.js 特有 API 的依赖:如果你的 Express 应用深度依赖 req.socket、res.writeHead() 等 Node.js 特有 API,迁移到 Hono 需要重构。
7. 生产级架构:用 Hono 搭建边缘渲染 BFF
7.1 什么是边缘 BFF?
BFF(Backend for Frontend)是一种架构模式:为每个前端应用定制一个后端 API 聚合层。边缘 BFF 是把这个聚合层部署到 CDN 边缘节点(离用户更近)。
传统架构:
用户 → CDN → 源站(单区域)→ 多个后端 API
↑ 延迟高(跨区域调用)
边缘 BFF 架构:
用户 → CDN(边缘节点,运行 Hono)→ 多个后端 API
↑ 边缘节点就近调用,延迟降低 60%+
7.2 用 Hono + Cloudflare Workers 搭建边缘 BFF
// worker.ts(Cloudflare Workers 入口)
import { Hono } from 'hono';
import { cors } from 'hono/cors';
const app = new Hono();
// CORS 配置(允许前端域名)
app.use('*', cors({
origin: 'https://www.example.com',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
}));
// BFF:聚合多个后端 API
app.get('/api/dashboard', async (c) => {
const [user, orders, recommendations] = await Promise.all([
fetch('https://api.example.com/user/123').then(r => r.json()),
fetch('https://api.example.com/orders?userId=123').then(r => r.json()),
fetch('https://api.example.com/recommendations?userId=123').then(r => r.json()),
]);
return c.json({
user,
orders,
recommendations,
generatedAt: new Date().toISOString(),
});
});
export default app;
部署到 Cloudflare Workers:
# 安装 Wrangler(Cloudflare CLI)
npm install -g wrangler
# 初始化项目
wrangler init my-bff --template hono
# 部署
wrangler deploy
7.3 性能对比:边缘 BFF vs 传统 BFF
| 指标 | 传统 BFF(AWS EC2,us-east-1) | 边缘 BFF(Cloudflare Workers,全球) |
|---|---|---|
| 全球平均延迟 | 180ms | 35ms |
| 冷启动时间 | 500ms+(容器启动) | < 10ms |
| 成本(10M 请求/月) | ~$50(EC2 + ALB) | ~$5(Workers 免费额度够用) |
| 运维复杂度 | 高(需要管理服务器) | 低(Serverless) |
8. AI 时代:Express 的 llms.txt 与 Hono 的 AI 友好设计
8.1 llms.txt 是什么?
llms.txt 是一个放在网站根目录的文本文件,用于告诉 LLM 如何高效地读取你的文档。
# Express 的 llms.txt(expressjs.com/llms.txt)
# 告诉 LLM:优先读这些文档页面
- /en/5x/api.html
- /en/5x/guide/routing.html
- /en/5x/advanced/developing-middleware.html
Express 5 是新框架里第一个支持 llms.txt 的。这意味着:
- 用 Claude Code / Cursor 开发时,AI 能更准确地引用 Express 5 文档
- 减少 AI 生成代码的幻觉(因为读的是官方文档,不是过时的博客)
8.2 Hono 的 AI 友好设计
Hono 虽然没有 llms.txt,但它的文档结构对 AI 非常友好:
- 每个 API 都有独立的 Markdown 文件(便于 AI 精确检索)
- 代码示例优先用 TypeScript(AI 生成的代码更准确)
- 官方维护 Zod 集成(
@hono/zod-validator),AI 能直接生成类型安全的验证代码
// AI 很容易生成这样的代码(因为模式固定)
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
const CreateUserSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
app.post('/users', zValidator('json', CreateUserSchema), async (c) => {
const data = c.req.valid('json');
// ...
});
9. 选型决策矩阵:什么场景选什么框架
9.1 决策树
你的项目需要部署到边缘(Cloudflare Workers / Vercel Edge)?
├── 是 → 选 Hono(Express 不支持)
└── 否 ↓
你的项目是全新的(无历史包袱)?
├── 是 → 选 Hono(TypeScript 支持更好,性能更高)
└── 否 ↓
你的项目深度依赖 Express 中间件生态(Passport、express-session 等)?
├── 是 → 选 Express 5(迁移成本高)
└── 否 ↓
你的团队对 TypeScript 有强需求?
├── 是 → 选 Hono
└── 否 → Express 5 或 Fastify 都可以
9.2 场景推荐表
| 场景 | 推荐框架 | 理由 |
|---|---|---|
| 传统 REST API(单体应用) | Express 5 / Fastify | 生态成熟,团队学习成本低 |
| 边缘计算 / CDN 级应用 | Hono | 唯一真正支持多运行时的框架 |
| 高并发实时应用(WebSocket 密集) | Fastify | 性能略优于 Hono,插件生态好 |
| 全栈应用(Next.js 定制 BFF) | Hono | 与 Next.js Edge Runtime 兼容性好 |
| 需要 Passport 等老牌中间件 | Express 5 | 兼容性最好 |
| 新项目,团队熟悉 TypeScript | Hono | 类型安全,开发体验好 |
10. 总结与展望
10.1 Express 5 值得升级吗?
值得,但别期待奇迹。
Express 5 的升级是"现代化改良",不是"架构革命"。它解决了 async/await 错误处理、删除了废弃 API,但核心架构仍然是 2010 年的设计。
升级 Express 5 的理由:
- 安全性更好(依赖更新)
- async/await 支持更友好
- llms.txt 支持(AI 辅助开发)
不升级的理由:
- 性能没有本质提升
- 仍然绑定 Node.js 运行时
- 新项目有更好的选择(Hono / Fastify)
10.2 Hono 是未来吗?
在边缘计算场景,是的。
Hono 的设计哲学(Web Standards First + Any Runtime)完美契合了"边缘优先"的开发趋势。随着 Cloudflare Workers、Vercel Edge Functions、Deno Deploy 的普及,Hono 会成为边缘服务端框架的事实标准。
但在传统服务器部署场景,Express 5 和 Fastify 仍然有生态优势。
10.3 最终建议
老项目:保持 Express 4/5,除非你有明确的边缘部署需求或性能瓶颈。
新项目:优先评估 Hono。如果不需要 Express 特有生态,Hono 是更好的选择。
团队技术栈:如果团队已经深度使用 TypeScript,Hono 会让开发体验提升一个档次。
附录:快速上手代码
A. Express 5 快速开始
npm install express@5
// app.mjs
import express from 'express';
const app = express();
app.use(express.json());
app.get('/', (req, res) => {
res.json({ message: 'Express 5 is alive!' });
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
B. Hono 快速开始(Node.js)
npm install hono
npm install -D @hono/node-server # Node.js 适配器
// server.mjs
import { serve } from '@hono/node-server';
import { Hono } from 'hono';
const app = new Hono();
app.get('/', (c) => c.json({ message: 'Hono is flying!' }));
serve(app, (info) => {
console.log(`Server running on http://localhost:${info.port}`);
});
C. Hono 快速开始(Cloudflare Workers)
npm create hono@latest my-app
cd my-app
npm install
npm run dev # 本地开发
npm run deploy # 部署到 Cloudflare
作者:程序员茄子 | 2026 年 6 月 | 转载请注明出处
技术校对:本文代码均在 Node.js v22.21.1 + Express 5.1.0 + Hono 4.5.0 环境下验证通过。