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 分钟跑起来,你就知道这个方案到底适不适合你了。

评论区

0 条评论

登录后可评论。

查看完整榜单
查看完整榜单
查看完整榜单