编程 Snapchat 开源 Valdi:用 TSX 写 UI,编译成原生视图,没有 WebView 也没有 JS Bridge

2026-10-03 00:04:11

Snapchat 开源 Valdi:用 TSX 写 UI,编译成原生视图,没有 WebView 也没有 JS Bridge

仓库:Snapchat/Valdi,C++ / TypeScript,MIT 许可,当前标记为 Beta。

它解决的问题很直白:用声明式 TypeScript 写 UI,一套代码编译成 iOS / Android / macOS 的原生视图。没有 WebView,也没有 JavaScript Bridge。Snapchat 自己的生产 App 里已经用了 8 年,之所以还挂 Beta,是工具链和文档要在开源环境里再打磨一轮,开发者体验满意后才会摘掉。

一个 TSX 组件长什么样

import { Component } from 'valdi_core/src/Component';

class HelloWorld extends Component {
onRender() {
const message = 'Hello World! 👻';

;
}
}

组件的渲染写在 onRender 里,布局属性直接挂在标签上。组件库单独拆了一个仓库:Snapchat/Valdi_Widgets。

装起来跑一下

npm install -g @snap/valdi
valdi dev_setup   # 一键装依赖
mkdir my_project && cd my_project
valdi bootstrap
valdi install ios   # 或 android

前置只有 Xcode(仅 macOS),其余依赖由 dev_setup 处理。建议装上 VSCode / Cursor 扩展,语法高亮之外还能看调试和热重载时的设备日志。

仓库的 apps/ 目录 里有可直接读的示例:helloworld(最小组件)、navigation_example(页面导航)、managed_context_example(用 managed context 跨组件共享状态)、valdi_gpt(运行时描述 UI,AI 驱动的动态 UI)、cli_example(构建 Valdi CLI 应用)、benchmark(性能基准)。

机制:原生性能从哪来

关键在于编译路径。TSX 组件不跑在解释器 + 桥接层上,而是编译成各平台的原生视图。围绕这条路径,还有几个具体设计:

  • 视图回收池:全局的视图池系统在所有页面之间复用原生视图,降低 inflation 延迟。
  • 组件独立重渲染:某个组件更新不会把父组件一起拖着重渲染,增量更新代价更小。
  • C++ 布局引擎:布局在主线程执行,跨语言 marshalling 开销极小。
  • viewport-aware 渲染:只 inflate 可见视图,无限滚动默认就是高效的。

写代码时的循环

目标是消掉传统的「编译—测试—调试」三段式:

  • 热重载:iOS / Android / 桌面上毫秒级看到改动,不用重新编译。
  • VSCode 内调试:断点、变量检查、性能剖析、heap dump 都在编辑器里完成。
  • TSX + TypeScript:类型安全覆盖到 UI 层。

接进现有 App 的两种方式

不需要重写整个 App,可以小步接入:

  • Embed Valdi in native:把 Valdi 组件塞进已有的 UIKit 或 Android view 层级。
  • Embed native in Valdi:通过 `` 在 Valdi 布局里放平台专属视图。

再往上还有 polyglot 模块:性能关键路径用 C++、Swift、Kotlin、Objective-C 写,通过类型安全绑定给 TypeScript 调用。以及 full-stack 架构——用 worker 线程跑后台处理,整个 feature 都用 Valdi 写,省掉平台专属的 bridge 代码。

原生集成与工程化

  • 自动代码生成:TypeScript interface 编译成 Kotlin、Objective-C、Swift 绑定。
  • 通过 polyglot 模块直接访问平台 API 和第三方原生库,TypeScript 与原生代码之间可以双向传复杂数据结构和回调。
  • 原生 protobuf 支持。
  • Flexbox 布局,自动 RTL。
  • Worker threads,多线程 JavaScript 执行。
  • 原生动画与平台手势处理。
  • 内置测试框架,支持组件级单元测试。
  • Bazel 集成,可复现的增量构建。

适用与不适用

适合的场景:已有原生 App、想按页面或功能逐步替换 UI 层;列表和长滚动对性能敏感;需要复用平台原生视图、原生库和已有的 C++ / Swift / Kotlin 代码。

不太合适的场景:团队完全不碰原生工程链路(Xcode、Android 构建、Bazel),polyglot 和原生接入这部分能力发挥不出来;目标平台只有 Web,Valdi 的编译产物是 iOS / Android / macOS 原生视图,不覆盖这条路径。

与 React Native、Flutter 的位置差异

React Native 走的是 JS 运行时加原生视图,通信层从 Bridge 演进到 JSI,但中间仍有跨语言调用;Flutter 是自己画,Skia / Impeller 接管全部渲染,UI 表现一致但不是平台原生控件。Valdi 的选择是把 TSX 编译成原生视图,既不要桥,也不要自绘引擎——代价是它必须对每个目标平台做原生集成,而不是靠一个渲染引擎通吃。

2025 年 11 月中旬到 12 月开源 Beta 之后,Callstack 等团队做过评测,普遍认为它在原生性能与开发效率之间提供了一条新路径,是 React Native 的有力竞争者。

许可证:MIT(见仓库 LICENSE.md)。

推荐文章

程序员茄子在线接单