Deno 2.5 + KV 2.0 全栈实战 2026:边缘 Serverless 运行时新王
Deno 2.5 正式发布,KV 2.0 + Queues GA + Fresh 3.0。本文完整实战 Deno 全栈:TypeScript 原生、KV 分布式存储、Fresh 框架、部署到 Deno Deploy,30 分钟上线一个生产级 SaaS。
今日技术简讯
📰 技术简讯 · 2026-09-06
今日聚合 6 条热门技术内容(中文素材优先)。
⚙️ 后端 / 架构
1. Deno 2.5 正式发布
- 链接:https://deno.com/blog/v2.5
- 来源:Deno
- 摘要:Deno 2.5 推出 KV 2.0(分布式键值存储 GA)+ Queues GA + 全栈框架 Fresh 3.0。
2. Cloudflare Workers + Durable Objects 新增 SQL
- 链接:https://blog.cloudflare.com/workers-sql-do
- 来源:Cloudflare
- 摘要:Durable Objects 新增 SQLite 接口,10GB 存储免费,边缘节点 SQL 查询 < 5ms。
3. Kubernetes 1.34 推出 Serverless 模式
- 链接:https://kubernetes.io/blog/1-34-release
- 来源:Kubernetes
- 摘要:K8s 1.34 推出 KEP-3960 Serverless Pod,冷启动 < 100ms,无需 Knative。
🎨 前端 / Web
4. SvelteKit 3 + Svelte 6 GA
- 链接:https://svelte.dev/blog/svelte-6-sveltekit-3
- 来源:Svelte
- 摘要:Svelte 6 推出 Runes GA + 全新的响应式系统,编译时优化再升级。
🤖 AI / LLM
5. LangChain.js v1.0 GA
- 链接:https://blog.langchain.dev/langchain-js-v1
- 来源:LangChain
- 摘要:LangChain.js v1.0 GA,统一 Python/JavaScript API,重写核心抽象,体积缩小 60%。
🚀 独立开发 / OPC
6. Stripe 推出 Lifetime Deal 工具
- 链接:https://stripe.com/blog/lifetime-deals
- 来源:Stripe
- 摘要:Stripe 推出 Lifetime Deal 一键配置(一次性付费订阅),独立开发者无需自建订单系统。
数据来源:掘金 / InfoQ 中文 / 即刻 / 少数派 / HN 采集日期:2026-09-06 (UTC+8)
今日深度文
Deno 2.5 + KV 2.0 全栈实战 2026:边缘 Serverless 运行时新王
2026 年的后端运行时市场,Deno 已经不再是"小众实验品" — 它用 5 年时间完成了 Node.js 用了 10 年才走完的路:内置 TypeScript、内置测试、内置格式化、内置 lint、内置 KV / Queues / Cron。本文的目的是:30 分钟内,用 Deno + Fresh + Deno KV,从零上线一个生产级 SaaS。
一、为什么 Deno 2.5 是 Serverless 时代的答案
1.1 Serverless 的三大痛点
云厂商的 Serverless(FaaS)虽然火,但开发者苦不堪言:
- 冷启动:Lambda / Cloud Functions 首次调用 500ms – 2s
- Vendor Lock-in:每个云厂商一套 API,迁移成本极高
- 本地开发体验差:必须用厂商 CLI / 模拟器,无法在本地"完全复刻云端"
Deno 2.5 通过三个特性同时解决这三个问题:
- 冷启动 < 50ms:V8 Snapshot + 预编译 wasm,单函数启动比 Node.js 还快
- 跨云兼容:同一份代码可以跑在 Deno Deploy / Cloudflare / AWS / 本地
- 本地即生产:
deno run直接跑,没有任何特殊运行时
1.2 Deno vs Node.js vs Bun(2026 年 9 月)
| 维度 | Deno 2.5 | Node.js 22 | Bun 1.3 |
|---|---|---|---|
| TypeScript 原生 | ✅ 内置 | ❌ 需要 ts-node / swc | ✅ 内置 |
| 标准库 | ✅ 官方丰富 | ✅ npm 包 | ⚠️ 部分 |
| 内置 KV / DB | ✅ Deno KV 2.0 | ❌ 无 | ❌ 无 |
| 包管理器 | ✅ deno install | ⚠️ npm (慢) | ✅ bun install (快) |
| npm 兼容 | ✅ 完全 | ✅ 原生 | ✅ 完全 |
| 冷启动 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| 生态成熟度 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
2026 年的现实选择:
- 想用 npm 生态 + 性能:Bun 1.3
- 想极致稳定 + 最大生态:Node.js 22
- 想"零配置全栈":Deno 2.5(自带 KV / Queues / Cron / Fresh)
二、Deno KV 2.0:分布式键值存储 GA
2.1 核心概念
Deno KV 是 Deno 内置的分布式键值存储,类似 Redis 但更强大:
- 强一致性:默认 eventual consistency,可配置 strong
- 全球分布式:基于 Deno Deploy 的边缘节点
- 事务支持:ACID 事务,跨 key 原子操作
- 二级索引:支持 list / atomic 操作
2.2 基础 CRUD
// kv.ts
const kv = await Deno.openKv();
// Set
await kv.set(["users", "u_123"], {
name: "Alice",
email: "alice@example.com",
createdAt: Date.now(),
});
// Get
const user = await kv.get(["users", "u_123"]);
console.log(user.value);
// Delete
await kv.delete(["users", "u_123"]);
// List(带 prefix)
const users = kv.list({ prefix: ["users"] });
for await (const entry of users) {
console.log(entry.key, entry.value);
}
2.3 原子事务
// 转账:从 A 账户扣 100,加到 B 账户
const result = await kv.atomic()
.check({ key: ["accounts", "A"], versionstamp: accountA.versionstamp })
.set(["accounts", "A"], { balance: accountA.balance - 100 })
.set(["accounts", "B"], { balance: accountB.balance + 100 })
.set(["transactions", crypto.randomUUID()], {
from: "A",
to: "B",
amount: 100,
timestamp: Date.now(),
})
.commit();
if (!result.ok) {
throw new Error("Transaction failed (A's balance changed)");
}
2.4 二级索引(KV 2.0 新增)
// 主键:users/u_123
// 二级索引:users/by_email/alice@example.com -> u_123
await kv.atomic()
.set(["users", "u_123"], user)
.set(["users", "by_email", user.email], "u_123")
.commit();
// 通过 email 查询
const userIdEntry = await kv.get(["users", "by_email", "alice@example.com"]);
const userEntry = await kv.get(["users", userIdEntry.value]);
三、Fresh 3.0:Islands 架构 SSR 框架
3.1 什么是 Fresh
Fresh 是 Deno 官方的全栈 Web 框架,灵感来自 Astro:
- 默认 SSR:服务端渲染,SEO 友好
- Islands 架构:只对交互组件做客户端 hydration
- 零 JS by default:首屏 0 KB JavaScript
3.2 创建一个 Fresh 项目
deno run -A -r https://fresh.deno.dev my-saas
cd my-saas
deno task start
3.3 项目结构
my-saas/
├── deno.json # 配置 + 任务
├── main.ts # 入口
├── dev.ts # 开发模式
├── routes/ # 文件路由(Next.js 风格)
│ ├── index.tsx # /
│ ├── api/
│ │ └── users.ts # /api/users
│ └── dashboard.tsx # /dashboard
├── islands/ # 客户端交互组件
│ └── Counter.tsx
├── components/ # SSR-only 组件
│ └── Layout.tsx
├── static/ # 静态资源
└── utils/
└── kv.ts # Deno KV 封装
3.4 路由示例
// routes/index.tsx
import { Handlers, PageProps } from "$fresh/server.ts";
interface Data {
users: { name: string; email: string }[];
}
export const handler: Handlers<Data> = {
async GET(_req, ctx) {
const kv = await Deno.openKv();
const users: any[] = [];
for await (const entry of kv.list({ prefix: ["users"] })) {
if (entry.key[1] !== "by_email") users.push(entry.value);
}
return ctx.render({ users });
},
};
export default function Home({ data }: PageProps<Data>) {
return (
<main class="max-w-4xl mx-auto p-6">
<h1 class="text-3xl font-bold">用户列表</h1>
<ul class="mt-4 space-y-2">
{data.users.map((u) => (
<li class="p-3 bg-gray-50 rounded">
<strong>{u.name}</strong> — {u.email}
</li>
))}
</ul>
</main>
);
}
3.5 Island 组件(客户端交互)
// islands/Counter.tsx
import { useState } from "preact/hooks";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div class="flex items-center gap-3">
<button
onClick={() => setCount(count - 1)}
class="px-3 py-1 bg-red-100 rounded"
>
-
</button>
<span class="text-xl font-bold">{count}</span>
<button
onClick={() => setCount(count + 1)}
class="px-3 py-1 bg-green-100 rounded"
>
+
</button>
</div>
);
}
在路由中使用:
import Counter from "../islands/Counter.tsx";
export default function Home() {
return (
<main>
<h1>My SaaS</h1>
<Counter /> {/* 只这个组件会被 hydrate */}
</main>
);
}
四、完整实战:30 分钟做一个 SaaS
我们要做一个极简的 Todo SaaS,功能:
- 用户注册 / 登录
- 每个用户有自己的 Todo 列表
- 支持实时同步(Deno Queues)
4.1 用户认证(基于 KV)
// utils/auth.ts
import { crypto } from "std/crypto/mod.ts";
export async function hashPassword(password: string): Promise<string> {
const salt = "static-salt-2026";
const data = new TextEncoder().encode(password + salt);
const hash = await crypto.subtle.digest("SHA-256", data);
return btoa(String.fromCharCode(...new Uint8Array(hash)));
}
export async function createUser(email: string, password: string) {
const kv = await Deno.openKv();
const userId = crypto.randomUUID();
const passwordHash = await hashPassword(password);
// 原子操作:检查 email 不存在 + 创建用户 + 建二级索引
const result = await kv.atomic()
.check({ key: ["users", "by_email", email], versionstamp: null })
.set(["users", userId], {
email,
passwordHash,
createdAt: Date.now(),
})
.set(["users", "by_email", email], userId)
.commit();
if (!result.ok) throw new Error("Email already exists");
return userId;
}
export async function login(email: string, password: string) {
const kv = await Deno.openKv();
const userIdEntry = await kv.get(["users", "by_email", email]);
if (!userIdEntry.value) return null;
const userEntry = await kv.get(["users", userIdEntry.value]);
const user = userEntry.value as any;
const passwordHash = await hashPassword(password);
if (passwordHash !== user.passwordHash) return null;
return userIdEntry.value;
}
4.2 Todo CRUD
// utils/todos.ts
const kv = await Deno.openKv();
export async function listTodos(userId: string) {
const todos: any[] = [];
for await (
const entry of kv.list({ prefix: ["todos", userId] })
) {
todos.push({ id: entry.key[2], ...entry.value });
}
return todos;
}
export async function createTodo(userId: string, title: string) {
const todoId = crypto.randomUUID();
await kv.set(["todos", userId, todoId], {
title,
completed: false,
createdAt: Date.now(),
});
return todoId;
}
export async function toggleTodo(userId: string, todoId: string) {
const entry = await kv.get(["todos", userId, todoId]);
const todo = entry.value as any;
if (!todo) throw new Error("Todo not found");
await kv.set(["todos", userId, todoId], {
...todo,
completed: !todo.completed,
});
}
export async function deleteTodo(userId: string, todoId: string) {
await kv.delete(["todos", userId, todoId]);
}
4.3 API 路由
// routes/api/todos.ts
import { Handlers } from "$fresh/server.ts";
import { listTodos, createTodo } from "../../utils/todos.ts";
import { getCurrentUser } from "../../utils/auth.ts";
export const handler: Handlers = {
async GET(req) {
const userId = await getCurrentUser(req);
if (!userId) return new Response("Unauthorized", { status: 401 });
const todos = await listTodos(userId);
return Response.json(todos);
},
async POST(req) {
const userId = await getCurrentUser(req);
if (!userId) return new Response("Unauthorized", { status: 401 });
const { title } = await req.json();
if (!title) return new Response("Title required", { status: 400 });
const id = await createTodo(userId, title);
return Response.json({ id });
},
};
4.4 部署到 Deno Deploy
# 1. 安装 deployctl
deno install -A -r https://deno.land/x/deploy/deployctl.ts
# 2. 登录(Deno Deploy 会打开浏览器)
deployctl login
# 3. 一键部署
deployctl deploy --project=my-saas main.ts
部署后自动获得:
- ✅ 全球 CDN(边缘节点 200+)
- ✅ HTTPS 自动配置
- ✅ KV 自动扩容(无需配置)
- ✅ 免费额度:1M 请求/月 + 1GB KV 存储
五、Deno Queues:异步任务队列
Deno 2.5 新增 Queues GA,类似 AWS SQS 但开箱即用。
5.1 发送任务
const kv = await Deno.openKv();
const queue = await kv.enqueue("send-email", {
delay: 5000, // 5 秒后执行
keysIfUndelivered: [["email-failures", messageId]],
});
5.2 处理任务(listenQueue)
// main.ts
import { listenQueue } from "deno:kv";
listenQueue(async (payload) => {
if (payload === "send-email") {
await sendWelcomeEmail();
} else if (payload.type === "send-email-to") {
await sendEmail(payload.to);
}
});
六、生产环境最佳实践
6.1 配置 deno.json
{
"tasks": {
"dev": "deno run -A --watch main.ts",
"build": "deno run -A dev.ts build",
"start": "deno run -A main.ts",
"test": "deno test -A",
"lint": "deno lint",
"fmt": "deno fmt"
},
"imports": {
"fresh": "jsr:@fresh/core@^3.0.0",
"preact": "npm:preact@^10.22.0",
"@preact/signals": "npm:@preact/signals@^1.3.0",
"std/": "jsr:@std/"
},
"fmt": {
"lineWidth": 100,
"indentWidth": 2,
"semiColons": true,
"singleQuote": false
},
"lint": {
"rules": {
"tags": ["recommended"]
}
},
"nodeModulesDir": "auto"
}
6.2 性能优化
// 1. KV 连接复用
const kv = await Deno.openKv();
// 2. 批量读取(避免循环 await)
const entries = await kv.getMany([
["users", "u_1"],
["users", "u_2"],
["users", "u_3"],
]);
// 3. 用 watch 监听变化(实时同步)
kv.watch([["todos", userId]]); // 监听当前用户的 todos
6.3 安全建议
// main.ts
import { load } from "std/dotenv/mod.ts";
await load({ export: true });
// 强制生产环境必须设置关键环境变量
if (Deno.env.get("DENO_ENV") === "production") {
if (!Deno.env.get("JWT_SECRET")) {
throw new Error("JWT_SECRET required in production");
}
}
七、未来展望:Deno + AI
2026 年的一个趋势:Deno 正在成为 AI Agent 运行时的首选:
- Python 互操作:Deno 2.5 原生支持
python -m,可直接调用 PyTorch - Deno KV:天然适合 Agent 状态管理
- 边缘部署:Agent 在用户附近运行,延迟 < 50ms
// AI Agent 示例(伪代码)
const llm = await import("npm:@anthropic-ai/sdk");
const agent = new Agent({
llm: new llm.Anthropic(),
tools: [searchTool, calculatorTool],
state: kv, // 直接用 Deno KV 作为 Agent 状态存储
});
await agent.run("帮我订明天下午 3 点的会议室");
八、结语
Deno 2.5 + KV 2.0 + Fresh 3.0 已经构成一个完整的全栈 Serverless 方案:
- 运行时:Deno(V8 + TypeScript 原生)
- 存储:Deno KV(分布式、强一致、免费)
- 框架:Fresh(Islands 架构、首屏 0 KB)
- 部署:Deno Deploy(全球边缘、零配置)
- 队列:Deno Queues(异步任务)
- 定时任务:Deno Cron
30 分钟,从 0 到生产。这就是 Deno 的承诺。
参考资料
�� 同主题文章
React 20 + Server Components GA:现代前端架构完整实战
React 20 正式发布。Server Components GA + Actions API + 性能提升 30%。6 大框架对比 + 实战 + 迁移指南。
Hono + Cloudflare Workers 2026:边缘计算完整实战指南
边缘计算是 2026 年后端标配。本文 Hono / Cloudflare Workers / Vercel Edge / Deno 4 大方案对比 + 6 个实战 + 性能基准。
云原生 2026:从 K8s 到 Fly.io / Railway 的现代部署方案完整指南
2026 年独立开发者不再需要 K8s。本文 Fly.io / Railway / Render / Koyeb / Modal 5 大平台对比 + 4 个实战 + 选型决策树。