Rust First · 面向 AI 时代的全平台 Native UI 框架

一次构建,
全平台 Native

NSH 是一个 Rust First 的全平台 Native UI 框架:一套应用模型、一个工具链,构建 iOS、Android、macOS、Windows、Linux 和 Web 应用,每个平台都建立在系统自己的界面与交互之上;同一个引擎还能在发布之后下发团队编写或 AI 生成的新界面。

  • 系统的界面与交互UIKit、Android View、AppKit、Win32、GTK 4、HTML,系统的文本、输入法和无障碍;同一个菜单在桌面上弹出,在手机上从底部升起
  • Rust First完整应用编译成 Native 代码;需要快时用 TSX 写界面
  • Retained Mode只更新变化的视图,120 FPS,静止时几乎不占 CPU
  • AI-Friendly一套模型、一个 nsh 命令行;发布后还能下发 AI 生成的签名界面
一套应用,手机、桌面和 Web 都能运行
  • iOS
  • Android
  • macOS
  • Windows
  • Linux
  • Web
  • GPUI
  • 开源 · Apache-2.0
  • 由长桥(Longbridge)构建
CLInsh init my-app
Chat.tsx运行中
示例应用里的 AI 聊天,用 TSX 编写,在这里由 Native Shell 的 Web 运行时在浏览器中实时运行。回复是本地脚本模拟的流式输出;可以点建议或用 + 重放场景。
Native

Native,有两层含义

NSH 统一组件、状态、业务逻辑和 API;视觉由应用设计,视图与交互建立在平台自己的基础之上。

01

平台的基础设施

每个后端都用平台已有的东西构建界面:UIKit 视图、Android 视图、AppKit 视图、GTK 4 控件、用 Direct2D 和 DirectWrite 绘制的 Win32 窗口,以及用 CSS 设置样式的 HTML 元素。文本输入、选区、输入法和无障碍都来自平台。

02

平台的交互方式

同一个组件在每种设备上都按用户的习惯工作。Menu 在有指针的设备上是贴着触发点弹出的菜单,在手机上是从底部升起的面板;ContextMenu 用右键打开,在触屏上长按打开。应用只写一次菜单。

每个平台的后端

  • iOSUIKit · CoreText · iOS 15+--target ios
  • AndroidAndroid View · StaticLayout · API 28+--target android
  • macOSAppKit · CoreText · macOS 14+--target macos
  • WindowsWin32 · Direct2D · DirectWrite · 10 1809+--target windows
  • LinuxGTK 4 · Pango · GTK 4.14+--target linux
  • WebHTML · CSS · 现代浏览器--target web
  • GPUIGPUI · 嵌入 GPUI 与 GPUI Kit 应用(macOS / Windows / Linux)--target gpui
真正的跨平台

从手机到桌面,再到 Web

跨平台在这里的意思是:每种设备都得到它该有的应用。布局随窗口重组,输入方式随设备变化,业务逻辑保持一份。一个工程师可以写一次应用,并在每个目标上验证它。

布局随窗口重组

Flexbox 和 Grid 由 Taffy 排版,配合 Tailwind 断点(md:、lg:)和 Rust 里的 window() 尺寸:聊天应用在宽窗口里并排显示侧栏、会话列表和消息,在手机上一次显示一屏。

  • md:
  • window()
  • Taffy

每种设备的输入方式

桌面上是指针、悬停、右键、快捷键和焦点;手机上是触摸、手势、软键盘和页面导航。nsh/base 的基础组件同时承载两者,应用代码只有一份。

  • Menu
  • ContextMenu
  • NavStack

在每个目标上验证

nsh test 无界面地运行应用的测试,也能在 macOS、Windows、Linux 和 GPUI 窗口、iOS 模拟器、Android 设备或浏览器里,用平台自己的输入运行同样的测试。

  • nsh test
  • --target ios
  • --target web
Rust First

用 Rust 写应用,在合适的地方用 TSX

Rust 是编写完整 NSH 应用的一等语言:界面、逻辑和组件都编译成 Native 代码,带着 Rust 的所有权、类型、线程和 crates.io。TSX 是第二条路径,适合快速写界面、做插件和运行时下发的界面。两者运行在同一个引擎上,使用同样的基础元素、基础组件和 signal,TSX 页面还能直接导入你的 Rust 组件。

用 Rust 开发
src/lib.rs
use nsh_core::element::prelude::*;

#[component]
pub fn App() -> impl IntoElement {
    let count = signal(0);
    view()
        .items_center()
        .gap_4()
        .child(text(move || format!("Count: {}", count.get())))
        .child(
            view()
                .rounded_lg().bg(rgb(0x2563eb)).px_5().py_3()
                .on_press(move || count.update(|n| *n += 1))
                .child(text("Tap").text_color(white())),
        )
}
基础能力

建立在每个平台最擅长的东西之上

文本、输入、Native 组件和 Web 是 UI 框架里最难做好的部分,NSH 直接交给平台;它自己的力气花在引擎、基础组件和工具链上。

取自平台系统已经做好的,NSH 直接使用

系统的文本与输入

文本框就是平台的编辑器——UITextView、EditText、NSTextView、GTK 的 TextView、浏览器的输入框——带着系统的输入法、选区手柄、编辑菜单和快捷键;Windows 上是 NSH 基于 DirectWrite 和 IMM32 的编辑器。系统在新版本里对文本和输入的改进,应用直接获得。

  • UITextView
  • EditText
  • NSTextView
  • GtkTextView
  • DirectWrite

Native 组件与界面自然叠放

地图、网页视图、视频播放器和宿主注册的任何 Native 视图,都只是同一层级里的又一个子视图:它们与 NSH 的视图一起布局、裁剪、滚动和接收触摸,没有分层问题。

  • WebView
  • Video
  • nativeComponent

由 HTML 组成的 Web 应用

在 Web 上,NSH 渲染用 CSS 设置样式的 HTML 元素;浏览器负责滚动、选择文本和处理输入。nsh package --target web 发布一个按内容命名文件的静态网站,可以直接放进任何 CDN 缓存。

  • HTML
  • CSS
  • --target web

由 NSH 构建平台之上,NSH 自己的部分

Retained Mode:120 FPS,低 CPU

每个元素都是平台保留着的视图。一次变化只重新运行读到那个 signal 的表达式,只发送它改到的视图,每帧一次批量提交;没变的视图原样不动,Native 动画不经过 JS 逐帧计算。聊天、表单、列表这类日常界面因此在静止时几乎不占 CPU,在 ProMotion 屏幕上滚动和动画稳定在 120 FPS。

  • signal
  • MountBatch
  • Taffy
  • 120 FPS

行为来自 NSH,外观来自你

nsh/base 提供无样式的基础组件——导航、对话框、菜单、弹出层、标签页、复选框、面板——负责状态、焦点、键盘和无障碍;每个部分的样式由应用决定,用 Tailwind 类或类型化样式。

  • nsh/base
  • Menu
  • Dialog
  • Tailwind

一个工具链,人和 AI 都能用

一个 nsh 可执行文件负责创建、构建、类型检查、热更新开发、测试、打包和签名,覆盖每个目标平台,并自带 TSX 打包器和 TypeScript 检查器。每个 API 都有从 Rust 源码生成的类型声明,文档以 llms.txt 提供,AI agent 用同一套命令就能完成生成、运行、测试、修复和打包的整个循环。

  • nsh run
  • nsh test
  • nsh package
  • llms.txt
交付方式

一个完整的应用,或发布之后再下发的界面

独立应用是 NSH 的起点。在同一个引擎之上,应用还可以在运行时接收新界面——由团队编写,或由模型生成——以签名模块的形式,运行在宿主设定的沙箱里。

独立应用从这里开始

交付到六个平台

用 Rust、TSX 或两者编写应用,nsh package 把它打成可安装的 iOS、Android、macOS、Windows、Linux 应用,或一个静态网站。

$ nsh init my-app --template rust
$ nsh run my-app --target macos
$ nsh package my-app --target windows
# --template ts for TSX
# ios · android · macos · windows · linux · gpui · web
  • Rust 应用完整编译成 Native 代码
  • 每个目标一条命令
  • Rust 改动自动重建,TSX 热更新
快速上手
动态界面与插件

发布之后再扩展应用

在任意页面嵌入 NshAppView(iOS)、NshView(Android)、AppView(桌面与 GPUI 应用)或在网页里用 createPlayer,运行时加载签名的 TSX 模块。

let app = NshAppView()
try app.grantCapabilities(grants)
let info = try await app
  .loadPackage(at: file, trust: trust)
// verified, sandboxed, running
// NshView on Android, AppView elsewhere
  • 一个页面可以放多个模块
  • 宿主注册自己的 Native 组件
  • 更新按你的节奏下发
各平台的嵌入方式
AI 生成的界面

用界面而不是文字回答

模型为每次请求写一个模块,服务器检查并签名,应用在沙箱里以 Native 方式显示它。

import { mount, signal, View } from "nsh";

function Answer() {
  const range = signal("1W");
  return <View class="gap-3 p-4">…</View>;
}
mount(Answer);
  • 每个回答一个 TSX 文件
  • 下发前完成类型检查与 trace
  • 只拥有宿主授予的能力
签名与沙箱
动态交付

在服务器上生成,在设备上被信任

模块以 Ed25519 签名的 .nshpkg 到达,发布密钥由离线根密钥认证,设备端检查吊销列表;每个视图一个 QuickJS 虚拟机,内存、调用时长和节点数都有上限,只能使用宿主授予的能力。

在服务器上生成,在设备上被信任在服务器上生成,在设备上被信任
原则

原生视图与交互,
视觉由应用设计

同一个应用在每个平台上功能一致:一套组件、状态和逻辑。它在手指或指针下的手感、文本如何编辑、菜单如何打开——这些属于每个平台自己。

开始构建