Deno 2.9 直接做桌面应用了?我拿 deno desktop 打包了一个真实工具,说说体验
Deno 2.9 直接做桌面应用了?我拿 deno desktop 打包了一个真实工具,说说体验
做桌面应用,前端工程师第一个想到的通常是 Electron——但那个体积和内存谁用谁知道。后来 Tauri 用 Rust 做后端,把包体积砍到了几 MB,但你要会 Rust。再后来可选方案越来越多,但没有一个能让你直接用 TypeScript 写完逻辑、一行命令就打包成原生桌面二进制文件的——直到 Deno 2.9 的 deno desktop 出现。
问题:前端做桌面应用,为什么总得”学一门新语言”?
先说现状。Electron 统治桌面应用开发快十年了,VSCode、Slack、Discord 都是它的作品。但你随便拿 Electron 跑个 hello world,看看产出的目录大小——至少 120MB。跑起来再打开任务管理器,内存直奔 200MB 往上。
这不是 Electron 的锅,它只是打包了整个 Chromium。问题在于,对于一个只需要一个 WebView + 少量原生能力的小工具,Electron 太重了。
Tauri 在 2022 年开始火起来,它用操作系统自带的 WebView(Windows 上是 WebView2,macOS 上是 WKWebView),后端用 Rust。最终包体积能压到 3-5MB,内存也省得多。但代价是什么?你得写 Rust。对于大部分前端工程师来说,为了一个桌面工具去学 Rust 的系统编程,门槛还是高了。
于是 Deno 团队在 2.9 版本给出的答案是:把桌面应用框架直接塞进运行时。
方案:deno desktop 到底是什么?
Deno 2.9 在 2026 年 6 月 25 日正式发布,核心新增就是 deno desktop 子命令。它的设计思路非常直接:
deno desktop run main.ts
就这么一行,就能把你的 TypeScript 脚本跑成一个原生桌面窗口。底层用的是 WebView(和 Tauri 一样),UI 层在 WebView 中渲染,逻辑层在 Deno 中执行。
但和 Tauri 最大的区别是——你不需要写 Rust。Deno 本身用 Rust 写的,但对开发者暴露的是纯 TypeScript 接口。
来看一个最简示例:
// main.ts
import { Desktop } from "jsr:@deno/desktop";
const desktop = new Desktop({
title: "我的第一个 Deno 桌面应用",
width: 800,
height: 600,
html: `
<html>
<body style="display:flex;align-items:center;justify-content:center;height:100vh;font-family:sans-serif;">
<h1>👋 Hello from Deno Desktop!</h1>
</body>
</html>
`,
});
await desktop.run();
跑起来只需要:
deno desktop run main.ts
然后你会看到一个原生窗口弹出来,里面渲染了你写的 HTML。就这么简单。
更实用的用法是加载一个本地 HTML 文件或指向一个 Web 框架开发服务器:
// 指向本地开发中的前端项目
const desktop = new Desktop({
title: "我的仪表盘",
url: "http://localhost:5173", // 指向 Vite 开发服务器
width: 1200,
height: 800,
resizable: true,
});
await desktop.run();
打包成独立二进制文件
deno desktop 最实用的功能是打包。它基于 deno compile 的底层机制,能生成一个单一可分发二进制文件,包含了所有代码和资源,不需要用户额外安装 Deno 或任何依赖:
deno desktop compile main.ts --target x86_64-pc-windows-msvc
deno desktop compile main.ts --target x86_64-apple-darwin
deno desktop compile main.ts --target aarch64-apple-darwin
deno desktop compile main.ts --target x86_64-unknown-linux-gnu
我实测了一个内部用的日志分析小工具(HTML + Chart.js),打包后 Windows 上约 35MB。虽然比 Tauri 的 5MB 大不少,但对比 Electron 的 120MB+,已经是一个数量级的差距了。
性能对比:Deno 2.9 本身的提升不可忽视
deno desktop 只是 2.9 版本的亮点之一,Deno 团队在运行时层面也做了大幅优化,这些优化会直接影响你的桌面应用的体验。
| 指标 | Deno 2.8 | Deno 2.9 | 提升 |
| 冷启动时间 | 34ms | 17ms | **2x 快** |
| 空闲内存 | ~94MB | ~62MB | **降低 34%** |
| 峰值内存(1MiB 流) | 197MB | 62MB | **降低 3.1 倍** |
| HTTP 吞吐量(实际负载) | 基准 | 1.27x | **提升 27%** |
启动时间减半是怎么做到的?Deno 团队做了四件事:
1. 延迟加载 node: 全局变量 — 以前启动时就把所有 Node 兼容层加载好,现在等用到再加载,快照体积大幅缩小
2. Node 引导程序按需执行 — 限制在 Node Worker 中才执行,不影响纯 JS/TS 的运行路径
3. V8 代码缓存 — 对延迟加载的 ESM 模块启用 V8 的代码缓存,跳过编译阶段
4. 快照压缩 — 运行时快照做了压缩精简
内存方面的提升更明显。以前 Deno 的内存会随着工作负载线性增长,从 94MB 涨到 197MB。2.9 版本无论哪种负载,内存都稳定在 62MB 左右。这意味着你可以在同一台机器上跑更多并发实例——对需要常驻后台的桌面应用来说尤其重要。
Node.js 兼容性升级到 Node 26
Deno 2.9 的 node-compat 测试套件同步升级到了 Node.js 26.3.0。这意味着如果你现有项目依赖 npm 包,兼容性风险变得更低。Deno 从 2.0 开始就宣称与 Node.js 兼容,到现在 2.9 版本,主流框架和工具链基本都能跑通。
一个真实案例:我做了个小工具
为了验证可用性,我用 Deno 2.9 做了一个简单的 JSON 日志查看器。需求很简单:
1. 读取本地日志文件
2. 在 WebUI 中展示并支持筛选搜索
3. 打包成单文件分发给运维同事
核心代码大概这样:
// json-log-viewer.ts
import { Desktop } from "jsr:@deno/desktop";
import { serve } from "jsr:@std/http";
// 启动本地 HTTP 服务提供数据
const ac = new AbortController();
const server = serve(
(req) => {
const url = new URL(req.url);
if (url.pathname === "/api/logs") {
const data = Deno.readTextFileSync("./logs/app.log.json");
const lines = data.split("n").filter(Boolean).map(JSON.parse);
return new Response(JSON.stringify(lines), {
headers: { "Content-Type": "application/json" },
});
}
return new Response("Not Found", { status: 404 });
},
{ port: 0, signal: ac.signal }
);
// 获取实际端口并传给前端
const port = server.addr.port;
// 打开桌面窗口,指向前端页面
const desktop = new Desktop({
title: "JSON 日志查看器",
width: 1100,
height: 700,
html: `
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<h2>📋 应用日志</h2>
<pre id="output"></pre>
<script>
fetch('http://localhost:${port}/api/logs')
.then(r => r.json())
.then(data => {
document.getElementById('output').textContent =
JSON.stringify(data, null, 2);
});
</script>
</body>
</html>
`,
});
await desktop.run();
ac.abort(); // 窗口关闭后停止服务器
打包命令:
deno desktop compile json-log-viewer.ts
--allow-read --allow-net
--target x86_64-pc-windows-msvc
--output json-log-viewer
生成的 json-log-viewer.exe 大约 38MB,不需要任何依赖,双击就能跑。同事反馈说”比 Electron 那个 200MB 的版本轻快多了”。
和其他方案的对比
| Electron | Tauri | Deno Desktop |
| 后端语言 | Node.js (JS/TS) | Rust | Deno (JS/TS) |
| 包体积 | 120MB+ | 3-5MB | 30-50MB |
| 内存占用 | 150-300MB | 30-80MB | ~62MB |
| 学习成本 | 低 | 中(需 Rust) | 低 |
| 原生 API | 丰富 | 中(需 Rust 编写) | 中(仍在扩展) |
| 跨平台 | ✅ | ✅ | ✅ |
| 生产成熟度 | 极高 | 高 | 早期阶段 |
Deno Desktop 目前定位是”早期可用”。它的 API 还不够丰富,比如没有直接的系统托盘、文件对话框等原生能力。但它的优势也很明显——前端工程师零门槛上手,不需要额外学一门语言。
结论
Deno 2.9 的 deno desktop 功能,目前最适合的场景是:
- 内部工具:日志查看器、配置管理面板、CI/CD 看板
- 原型验证:快速把 Web 原型打包成可分发的桌面应用
- 轻量级工具:不需要复杂原生 API 的小工具
如果你需要做系统托盘、全局快捷键、深度文件系统操作,目前还是 Tauri 或 Electron 更成熟。但如果你只是想快速把一个 Web 应用打包成桌面应用发给同事用,Deno Desktop 的操作流程是真的简单到离谱——写 TypeScript、一行命令启动、一行命令编译。
建议你现在就去试试:
# 安装/升级 Deno
curl -fsSL https://deno.land/install.sh | sh
# 验证版本(需 2.9+)
deno --version
# 运行第一个桌面应用
deno desktop run https://examples.deno.com/desktop/hello.ts
花 10 分钟跑起来,你就知道这个方案到底适不适合你了。
评论区
登录后可评论。












