native-feel-skill: 跨平台原生质感桌面应用的 Agent Skill

> 一句话版本: yetone(avante.nvim 作者)把 Raycast 2.0 的技术架构和反编译结果打包成了一个 Agent Skill —— 任何 AI 编程助手装上后就知道怎么写出"感觉像原生"的跨平台桌面应用。不是 Electron 加皮肤,是真·四层架构。

背景:Raycast 2.0 的架构革命

Raycast 昨天(2026-05-14)刚刚发布了 2.0 公开测试版,这是它有史以来最大的更新 —— 从纯 macOS 原生 AppKit 应用,彻底重写成了 macOS + Windows 跨平台应用。

技术栈:TypeScript + Swift + C# + Rust + Node + React。

yetone 在发布的当天就反编译了 Raycast Beta.app v0.60.0,和 Raycast 官方的技术博文对照,提炼出了这个 Skill。

内容结构


native-feel-skill/
├── SKILL.md                    # Agent 入口
├── references/
│   ├── 01-philosophy.md        # 8 条架构原则
│   ├── 02-architecture.md      # 四层架构详解
│   ├── 03-webview-survival.md  # WebKit/WebView2 坑和修复(最高密度文件)
│   ├── 04-ipc-contract.md      # 跨语言类型化 IPC
│   ├── 05-memory-truths.md     # 为什么 Activity Monitor 骗了你
│   ├── 06-native-conventions.md # 70+ 原生质感检查项
│   └── 07-evidence-raycast.md  # 反编译 Raycast Beta 的证据
└── checklists/
    ├── decision-tree.md        # 你的项目该不该用这个架构?
    └── ship-readiness.md       # 75 项上线检查清单

八条架构原则

#原则核心思想
T1**把接缝放在渲染层**跨平台边界画在 WebView 表面:下面是原生(窗口、热键、材料),上面是共享(React、业务逻辑)
T2**一套 schema,多种语言**多语言系统通过统一 IDL + codegen 通信,手写 marshalling 是禁止的
T3**拥抱平台,别和它竞争**系统的模糊效果比你的快,系统的滚动条比你的对。不要重新发明平台功能
T4**性能是感知问题**Activity Monitor 的数字不是用户体验。用户感知到的是"点没点开",不是"多少 MB"
T5**短迭代循环就是产品**原生 UI 编译 30s vs React HMR 200ms —— 150 倍差距,一年下来就是"感觉做完了"和"感觉没做完"的差距
T6**有意图地跨越边界**每次 IPC 都是设计决策。批量化、缓存化、可观测化。禁止意外热循环
T7**身份认同是肌肉记忆**重写时可以改一切,但不能改用户习惯的快捷键和操作流。这些才是"那个 App"
T8**分离基线和边际成本**空 WebView 的 50MB 是租金,付了就认了。优化精力花在你的脏页上,别花在平台头上

四层架构


┌──────────────────────────────────────────────┐
│ 🏠 原生 Shell                               │
│ macOS: Swift/AppKit                          │
│ Windows: C#/.NET 8/WPF                       │
│ 负责:窗口、热键、菜单栏、系统托盘、全局快捷键  │
├──────────────────────────────────────────────┤
│ 🌐 系统 WebView                              │
│ macOS: WKWebView                             │
│ Windows: WebView2 (Chromium)                 │
│ 运行 React + TypeScript UI                   │
├──────────────────────────────────────────────┤
│ ⚙️ Node 后端                                  │
│ 单一长驻进程                                  │
│ 负责:数据库、扩展运行时、AI 服务              │
├──────────────────────────────────────────────┤
│ 🦀 Rust 核心                                  │
│ UniFFI 桥接,可分享给 iOS 和服务器             │
│ 文件索引器、云同步、高性能计算                  │
└──────────────────────────────────────────────┘

关键创新: 四层之间通过一套类型化 IPC schema 通信,codegen 为每一层生成类型安全的客户端。改 schema 会导致所有语言编译失败 —— 从根本上杜绝类型漂移。

决策树:该不该用这个架构?

问题如果...结论
OS 目标仅 macOS 或仅 Windows❌ 纯原生
原生质感"够好就行"❌ 用 Electron
冷启动预算<100ms❌ 纯原生
内存预算<150MB❌ 纯原生
研发周期<3 个月上线❌ 先用 Electron
✅ 最适合生产力启动器、笔记应用、AI 桌面端、开发工具✅ 推荐

WebView 生存指南(最有价值的部分)

这份 Skill 的反向工程揭示了一系列 WebKit 的具体坑和修复方案:

问题原因修复
WebKit 隐藏后卡动画系统认为 WebView 不可见时 throttle requestAnimationFramealphaValue=0 保持窗口可见 + 禁用 occlusion 检测
窗口展开时空白帧WebKit throttle 视口外区域WebView frame 一直保持展开尺寸,窗口再缩放
窗口缩放卡顿WebKit 在动画期间暂停绘制用 Core Animation 替代系统动画
打开窗口闪烁绘制未完成时显示窗口`_doAfterNextPresentationUpdate` 回调
Emoji 渲染慢字体回落链太长启动时预加载 emoji font
内存测量误导macOS 双倍计数共享框架看 dirty pages 和 compressed,不看 resident

实用场景

场景 1:已有的 Electron 应用太"网页味"

→ 跑 75 项检查清单,通常 6-8 个问题是常见的:

场景 2:新建跨平台原生质感应用

→ 先跑决策树,符合条件后:

1. 确定 IPC 契约(最重要,后面改成本最高)

2. WebView 生存配置

3. 内存卫生

评分

维度评分说明
实战价值★★★★★不是理论论文,是经过 Raycast 验证、反编译确认的可执行知识
内容密度★★★★★7 个参考文件 + 2 个清单,75 项检查清单,全是干货
唯一性★★★★☆市面上几乎没有把"原生质感"系统化成 Agent Skill 的同类项目
时效性★★★★★Raycast 2.0 昨天发布,这个 Skill 今天就有了
易用性★★★★★一句 `npx skills add` 安装,Agent 自动匹配触发

一句话总结

> 如果你在做跨平台桌面应用(macOS + Windows),又不想被用户说"这玩意儿一股网页味",装上这个 Skill —— 你的 AI 助手就会变成 Raycast 架构师,告诉你每条线该画在哪里、每个坑该怎么填。