Fresh
基于 Deno、Preact 与 Islands 架构,默认服务端渲染的全栈 Web 框架。
项目概述
Fresh 让页面默认在服务端渲染,只为显式标记的交互岛屿发送浏览器 JavaScript。它将文件路由、数据加载、表单、Partials 和部署能力整合进简洁的 Deno 开发体验。
Fresh 是以 Deno、Preact 和 Web 标准为基础的全栈 Web 框架,强调速度、可靠性与简单性。普通路由和组件默认只在服务端渲染并输出 HTML,不会自动把整棵组件树发送到浏览器;只有放在 islands 目录中的交互组件才会被水合,因此内容型页面可以实现默认零客户端 JavaScript。Fresh 2 同时提供 App 路由 API、文件系统路由、类型化 Handler、Middleware、Layouts、Partials、表单、WebSocket、View Transitions 和安全插件,并通过 Vite 处理开发与生产构建。它尤其适合希望使用 TypeScript 与 JSX 构建服务端优先网站,又只在必要区域加入细粒度交互的团队。
主要特点
Fresh 以服务端渲染为默认值,通过 Islands、Partials 和标准 Web API 在低客户端开销与现代交互之间取得平衡。
默认服务端渲染
每个路由默认在服务端渲染为 HTML;没有 Island 时不会向浏览器发送应用 JavaScript,减少解析和水合成本。
Islands 局部水合
只有 islands 或路由内 (_islands) 目录中的 Preact 组件会在客户端激活,可把搜索、购物车和编辑器等交互隔离到小范围。
Preact 与 Signals
使用轻量 Preact 组件模型,并可通过 Signals 表达细粒度响应状态;Signal 还能在服务端与 Island 之间安全序列化。
文件路由与 App API
既可通过 routes 目录、动态参数和嵌套 Layout 组织页面,也能直接在 App 上注册 GET、POST、WebSocket 和 Middleware。
服务端数据加载
Handler 在服务端读取数据库或 API,再通过 page() 将类型化数据传给组件,避免把密钥与敏感逻辑暴露到客户端。
Partials 渐进导航
服务器可以只返回并替换页面中的命名区域,让链接与表单获得应用式体验,同时保持 HTML 和渐进增强模型。
Web 平台能力
Route Handler 直接使用 Request、Response、FormData、Headers 等标准接口,并支持 WebSocket、View Transitions 和 OpenTelemetry。
内置安全与部署选项
提供 CORS、CSRF、CSP、IP Filter 等插件,可部署到 Deno Deploy、Docker、Cloudflare Workers,或编译为单一可执行文件。
适用场景
适合内容占比高、重视首屏性能和 SEO,并希望在 Deno 上同时处理页面、表单与 API 的 Web 产品。
内容与营销网站
默认 SSR 和极少客户端 JavaScript 适合文档、博客、品牌站与新闻内容,并有利于抓取和首屏展示。
电商与目录页面
商品列表在服务端输出,筛选、购物车等功能用 Islands 与 Partials 增强,可控制复杂交互的下载成本。
表单驱动应用
标准 POST Handler、FormData 和渐进增强适合注册、预约、后台录入及审批流程,即使客户端脚本失败也能工作。
个性化服务端页面
Handler 可根据 Cookie、Session 或数据库在服务器生成用户专属 HTML,并通过 Middleware 统一认证与状态。
Deno 全栈产品
页面、API、定时任务和数据访问可共享 TypeScript 类型、Deno 工具链与权限模型,减少多套工程配置。
边缘与容器部署
可根据延迟、运行时能力和基础设施要求选择 Deno Deploy、Cloudflare Workers、Docker 或编译二进制。
优点与注意事项
技术选型不仅要看能力,也要理解它带来的团队成本。
主要优点
Fresh 擅长的地方
- 默认不发送客户端 JavaScript,内容页面无需额外优化即可保持较低运行开销
- Island 边界明确,团队能精确控制哪些组件需要水合和浏览器状态
- 文件路由、Handler、Middleware、Layout 和 API 位于同一 TypeScript 工程
- Request、Response 与 FormData 等 Web 标准接口降低框架专属概念数量
- Preact 与 Signals 体积轻,适合局部高频交互和可序列化共享状态
- Deno 内置格式化、Lint、测试、权限和 TypeScript 支持,开发工具链较统一
- Partials 和标准表单提供渐进增强,不必为了局部导航引入完整 SPA
需要注意
采用前应考虑的问题
团队需要熟悉 Deno 的权限、任务、JSR 和部署方式;虽然可使用 npm 包,但应验证 Node 专属 API 与构建兼容性。
过多 Island 会增加客户端脚本与状态协调,边界过大则接近整页水合;应围绕真实交互需求拆分。
函数不能作为 Island Props 传递,复杂服务对象也不应进入浏览器;事件逻辑应留在 Island 内或通过表单和 API 连接。
模块在多个请求之间共享,不能把购物车、Session 或用户 Signal 放在顶层变量中,应创建请求级状态并持久化到安全存储。
复杂离线编辑器、画布应用或大量跨页面客户端状态可能更适合以 SPA 为中心的架构,而不是不断扩大 Islands。
从 1.x 迁移时需检查 App、路由、插件、Vite 和构建输出约定,不能直接套用旧版教程或示例。
Fresh 负责 Web 应用生命周期,但不会替项目决定数据库、ORM、队列或业务缓存,需要根据部署环境自行组合。
快速开始
使用 Fresh 2 创建服务端任务页面、表单 API、交互 Island 和无需监听端口的路由测试。
bashdeno run -Ar jsr:@fresh/init
cd fresh-project
deno task devtypescriptimport { page } from "fresh";
import { define } from "@/utils.ts";
type Task = {
id: string;
title: string;
completed: boolean;
};
const tasks: Task[] = [
{ id: "1", title: "学习 Fresh", completed: false },
];
export const handler = define.handlers({
GET() {
return page({ tasks });
},
async POST(ctx) {
const form = await ctx.req.formData();
const title = String(form.get("title") ?? "").trim();
if (!title || title.length > 120) {
return new Response("Invalid title", { status: 422 });
}
tasks.push({
id: crypto.randomUUID(),
title,
completed: false,
});
return new Response(null, {
status: 303,
headers: { location: "/tasks" },
});
},
});
export default define.page<typeof handler>(({ data }) => {
return (
<main>
<h1>任务</h1>
<form method="post">
<input name="title" required maxlength={120} />
<button type="submit">添加</button>
</form>
<ul>
{data.tasks.map((task) => <li key={task.id}>{task.title}</li>)}
</ul>
</main>
);
});typescriptimport { useSignal } from "@preact/signals";
export default function TaskFilter() {
const query = useSignal("");
return (
<label>
筛选任务
<input
value={query}
onInput={(event) => {
query.value = event.currentTarget.value;
}}
placeholder="输入关键词"
/>
<output>当前关键词:{query}</output>
</label>
);
}typescriptimport { define } from "@/utils.ts";
export const handlers = define.handlers({
GET() {
return Response.json({ status: "ok" });
},
async POST(ctx) {
const input = await ctx.req.json();
if (
typeof input !== "object" ||
input === null ||
typeof (input as { title?: unknown }).title !== "string"
) {
return Response.json(
{ error: "title must be a string" },
{ status: 422 },
);
}
return Response.json(
{
id: crypto.randomUUID(),
title: (input as { title: string }).title,
},
{ status: 201 },
);
},
});typescriptimport { expect } from "@std/expect";
import { App } from "fresh";
import { handlers } from "../routes/api/tasks.ts";
Deno.test("creates a task", async () => {
const handle = new App()
.post("/api/tasks", handlers.POST)
.handler();
const response = await handle(
new Request("http://localhost/api/tasks", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ title: "测试 Fresh" }),
}),
);
expect(response.status).toEqual(201);
expect((await response.json()).title).toEqual("测试 Fresh");
});下一步:默认把组件留在服务端,只有真正需要浏览器状态或事件的区域才放进 islands;数据库、密钥和权限判断应保留在 Handler 或 Middleware 中。
类似项目
这些框架同样覆盖服务端渲染、内容网站或边缘部署,也包括 Fresh 所依赖的 Deno 服务端生态。
Astro
面向内容网站的 Web 框架,默认发送更少的客户端 JavaScript。
查看项目Next.js
基于 React 的全栈 Web 框架,覆盖渲染、路由和部署。
查看项目Oak
受 Koa 启发、支持 Deno、Node.js、Bun 与 Cloudflare Workers 的 TypeScript 中间件框架。
查看项目Deno
默认支持 TypeScript 的安全 JavaScript、TypeScript 运行时。
查看项目Qwik City
基于 Qwik 可恢复执行模型,提供路由、数据加载和 Server Action 的全栈 Meta-framework。
查看项目Enhance
以 HTML、服务端渲染 Web Components 和渐进增强为核心的全栈多页应用框架。
查看项目Fresh vs Next.js
Fresh 与 Next.js 都能构建服务端渲染的全栈 React 风格应用,但默认理念不同。Fresh 基于 Deno 和 Preact,以零客户端 JavaScript起步并通过 Islands 显式增加交互;Next.js 基于 React,提供更广的渲染、缓存与平台生态。
| 比较维度 | Fresh | Next.js |
|---|---|---|
| 核心技术 | Deno、Preact、Signals 与 Web 标准 | Node.js 生态、React 与 React Server Components |
| 客户端默认值 | 普通组件只在服务端运行,Island 才水合 | Server Component 默认服务端,Client Component 进入客户端图 |
| 路由 | Fresh App API + routes 文件系统路由 | App Router、嵌套 Layout 与 Route Handler |
| 局部导航 | Partials 从服务端替换命名 HTML 区域 | 客户端 Router、RSC Payload 与 Streaming |
| 数据与缓存 | 标准 Handler/组件取数,缓存策略自行定义 | 框架级 Fetch、缓存、Revalidation 与动态渲染控制 |
| 生态规模 | Deno/JSR 与可兼容的 npm 生态,体量较小 | 庞大的 React、npm、托管平台与第三方集成 |
| 部署 | Deno Deploy、Docker、Workers、编译二进制 | Vercel、Node Server、Container 与多种适配平台 |
| 更适合 | 内容优先、渐进增强和低客户端脚本的网站 | 复杂 React 产品、成熟集成和多样缓存需求 |
如果团队希望从服务端 HTML 和零客户端 JavaScript 起步,只给少量区域加入交互,并愿意采用 Deno 与 Preact,Fresh 的模型非常直接;如果产品需要大型 React 生态、复杂客户端状态、成熟的托管集成或细粒度缓存能力,Next.js 通常选择更多。两者都能做全栈应用,关键区别在于客户端交互规模、运行时经验和平台依赖。
资料核验
版本、维护信息与本页采用的官方资料来源。
本次核验覆盖 Fresh 的核心定位、主要能力、官方入口与开源许可。项目版本持续更新,具体补丁版本、兼容性和迁移要求请在采用前继续核对官方发布记录。
官方仓库未归档,核验时最近可见的代码活动日期为 2026 年 7 月 4 日。该状态表示项目近期仍有公开维护活动,不代表固定发布频率或长期支持承诺。