一套 TypeScript 代码,编译成 macOS/iOS/Android/Linux/Windows 全平台原生应用:Perry 开源
MIT 开源协议。基于 Rust + SWC + LLVM 构建,将 TypeScript 直接编译为原生二进制文件——无需 Node.js、无需 Electron、无需运行时依赖。输出文件仅 2-5 MB。
一、Perry 是什么
Perry 是一个用 Rust 编写的原生 TypeScript 编译器,核心思路非常清晰:
输入 TypeScript → 输出各平台原生可执行文件
支持的平台:
- 桌面:macOS、iPadOS、Windows、Linux
- 移动:iOS、Android
- 可穿戴:watchOS、tvOS
- Web:WebAssembly + JavaScript
对比主流跨平台方案:
| 方案 | 运行时依赖 | UI 渲染 | 性能 | 体积 |
|---|---|---|---|---|
| Perry | 无 | 原生组件 | 极高 | 2-5 MB |
| Electron | Node.js + Chromium | Chromium | 中等 | 100-300 MB |
| React Native | JS 引擎 | 原生组件 | 高 | 10-20 MB |
| Flutter | 自带引擎 | Skia 自绘 | 高 | 10-30 MB |
| Tauri | 系统 WebView | WebView | 高 | 3-15 MB |
二、为什么选择 Perry
无需运行时
传统 Node.js 应用分发后,机器上必须安装 Node.js 环境。Perry 编译出来的是一个独立的原生二进制文件,双击即可运行,完全不依赖任何运行时。
这对以下场景极具价值:
- 分发给非技术用户:对方无需配置任何环境
- CLI 工具分发:一行命令安装,其他用户无需装 Node.js
- 嵌入式场景:资源受限环境
快速编译
Perry 使用 SWC(Rust 写的超快 JS/TS 编译器)做前端解析,配合 LLVM 优化代码生成,直接输出原生机器码。
流程:
TypeScript → SWC 解析 → AST → LLVM IR → 优化 → 原生机器码
没有中间层,没有解释执行,编译出来就是可以直接运行的二进制。
体积小巧
Perry 编译出来的二进制文件只有 2-5 MB。
如果需要使用纯 JavaScript npm 包(例如 Moment.js、Lodash),可以启用可选的 V8 运行时,此时体积为 15-20 MB——仍然远小于 Electron 的 100-300 MB。
可重现构建
相同输入 → 相同输出(相同二进制)
这解决了传统 Node.js 项目的痛点:同一份代码,在 A 机器上 npm install 装的是 A 版本依赖,在 B 机器上装的是 B 版本,最终打包出来的结果可能不一致。
Perry 的编译结果是确定的,换机器、换 CI、换团队都能完美复现。
全面的标准库
Perry 内置了 TypeScript 标准库的实现,覆盖了 Node.js 开发者熟悉的大部分 API:
- 文件系统:
fs - 路径处理:
path - 加密:
crypto - 系统信息:
os - 二进制数据:
Buffer - 子进程:
child_process
无需引入额外的 npm 包,直接使用标准 API。
可选 V8 运行时
如果确实需要使用纯 JavaScript npm 包,Perry 支持启用 V8 运行时模式,获得完整的 npm 生态兼容性。
这意味着你可以渐进式迁移:先用原生能力开发核心功能,再按需引入 npm 包。
三、25+ 原生 UI 组件
Perry 内置了 25+ 原生 UI 组件,且每个组件都是真正的平台原生实现,不是 Web 视图模拟的:
| 组件 | macOS/iOS | Android | Windows | Linux |
|---|---|---|---|---|
| 按钮 | AppKit | UIKit | Win32 | GTK4 |
| 文本框 | AppKit | UIKit | Win32 | GTK4 |
| 文本区域 | AppKit | UIKit | Win32 | GTK4 |
| 表格 | AppKit | UIKit | Win32 | GTK4 |
| Canvas | AppKit | UIKit | Win32 | GTK4 |
| 二维码 | AppKit | UIKit | Win32 | GTK4 |
| 安全输入框 | AppKit | UIKit | Win32 | GTK4 |
| 启动画面 | AppKit | UIKit | Win32 | GTK4 |
这意味着:
- 不需要 WebView:不是用 HTML/CSS 渲染,而是调用平台原生 API
- 原生外观:按钮、输入框看起来和系统原生应用完全一致
- 原生性能:UI 渲染不走浏览器引擎,没有额外的抽象层
四、编译时插件系统
Perry 的模块在编译时组合,这与运行时插件系统有本质区别:
传统运行时插件(Electron/Node.js):
主进程 ↔ IPC ↔ 插件进程
Perry 编译时插件:
TypeScript 代码 → 编译时内联 → 最终二进制文件中的原生函数调用
优势:
- 无运行时插件开销
- 无 IPC 通信延迟
- 依赖项直接编译进二进制,发布时只有一个文件
五、真正的多线程
Perry 支持真正的操作系统线程,而非 Node.js 的事件循环伪并发:
// 使用 parallelMap 并行处理
const results = parallelMap(items, (item) => {
return processItem(item); // 在独立线程中执行
});
// 使用 spawn 创建新线程
const worker = spawn(() => {
doHeavyComputation();
});
编译时安全性:Perry 的类型系统在编译时就拒绝可变捕获(mutable capture),确保不会有数据竞争。这意味着使用多线程不需要 SharedArrayBuffer,不需要 Worker API,代码安全且高性能。
六、编译时 i18n
Perry 内置了国际化(i18n)支持,在编译阶段完成字符串提取和翻译验证:
- 自动字符串提取:从代码中自动提取需要翻译的字符串
- 30+ 语言环境:支持 CLDR 复数规则
- 编译时验证:翻译缺失或错误在编译期就能发现
- 嵌入二进制:翻译数据直接编译进二进制文件,运行时查找开销几乎为零
import { t, plural } from '@perry/i18n';
const message = t('hello'); // 自动替换为当前语言环境的翻译
const count = plural('item_count', items.length); // 自动处理复数形式
七、快速开始
安装 Perry
# macOS / Linux
curl -fsSL https://perry-install.dev/install.sh | bash
# 或使用 cargo 安装
cargo install perry-cli
创建项目
perry new my-app
cd my-app
项目结构
my-app/
├── src/
│ ├── main.ts # 入口文件
│ ├── ui/ # UI 组件
│ └── utils/ # 工具函数
├── perry.config.ts # 配置文件
└── package.json
编写原生 UI
import { App, Button, TextField, Window } from '@perry/core';
const window = new Window({
title: '我的第一个 Perry 应用',
width: 800,
height: 600,
});
const button = new Button({
text: '点击我',
onClick: () => {
console.log('按钮被点击了!');
},
});
window.add(button);
window.show();
编译到各平台
# 编译为当前平台
perry build
# 编译为指定平台
perry build --target macos # macOS
perry build --target ios # iOS
perry build --target android # Android
perry build --target windows # Windows
perry build --target linux # Linux
perry build --target wasm # WebAssembly
输出示例
$ perry build --target macos
Compiling TypeScript...
Optimizing with LLVM...
Linking native binary...
✅ Done! Output: dist/my-app (3.2 MB)
八、性能对比
| 指标 | Perry | Electron | Tauri |
|---|---|---|---|
| 启动时间 | <100ms | 1-3s | 200-500ms |
| 内存占用 | 20-50MB | 200-500MB | 50-150MB |
| 二进制体积 | 2-5 MB | 100-300 MB | 3-15 MB |
| GPU 加速 | 原生支持 | WebGL | WebView |
| 系统集成 | 原生 API | 有限 | 有限 |
九、适用场景
Perry 非常适合:
- 需要同时覆盖桌面 + 移动端 + Web 的应用
- CLI 工具开发者,不想让用户装 Node.js
- 对性能、体积、启动速度有较高要求的场景
- 已有 TypeScript 技术栈,不想学新语言
Perry 目前不太适合:
- 需要大量 Web 生态库(React/Vue 等前端框架)的应用
- 复杂 Web 应用(此时 Tauri 可能是更好的选择)
- 还在快速迭代、需要灵活生态的项目
十、总结
Perry 的核心价值在于:
用 TypeScript 写一次,编译成所有平台的原生应用——没有 Electron,没有 WebView,没有运行时依赖。
它代表了一种新的跨平台开发思路:不是用 Web 技术模拟原生体验,而是真正把 TypeScript 编译成原生代码,用各平台原生 API 渲染 UI。
如果你厌倦了 Electron 的臃肿,又想要真正的跨平台原生体验,Perry 值得关注。
源码地址:https://github.com/PerryTS/perry
标签: #TypeScript #跨平台开发 #Rust #开源 #原生应用 #LLVM #SWC #Perry