在 canvas 上写 TSX。
Pingo 用函数组件、hooks 和 CSS 描述界面,但不生成 DOM:Rust/WASM 核心负责布局、 文本、命中、滚动、绘制与动画,TypeScript 外壳负责组件树与样式,两者之间只通过版本化 的二进制协议通信。写法是熟悉的,跑的是一条不经过 DOM 的渲染管线。
它适合这些场景:
- 长列表与表格——窗口由核心规划,百万行的代价等于一屏,滚动稳态完全不回调 JS。
- 主线程会被阻塞的应用——UI 时钟与渲染时钟相互独立,主线程卡住 200ms 画面仍然连续。
- canvas 内的文本编辑——caret、选区、IME 组合、剪贴板与撤销重做由引擎实现,业务 不必再为输入能力叠一层 HTML 控件。
想先看效果,Playground 里有百万行滚动、编辑与 IME、命中测试与双时钟的实时演示,右侧是逐帧指标。
pnpm add @dopejs/pingo业务只依赖 @dopejs/pingo 一个包。@dopejs/pingo-host、@dopejs/pingo-jsx 等是内部
实现包,不属于公开契约。
import { createElement, createHostedCanvasRoot } from "@dopejs/pingo";
const canvas = document.querySelector<HTMLCanvasElement>("#app")!;
canvas.width = 800;
canvas.height = 600;
const root = await createHostedCanvasRoot(canvas);
root.render(
createElement("container", {
width: 800,
height: 600,
backgroundColor: "#ffffffff",
padding: 24,
children: createElement("text", {
value: "Hello pingo",
fontSize: 24,
lineHeight: 32,
color: "#1f2329ff",
}),
}),
);createHostedCanvasRoot 自己探测浏览器能力,在 SharedArrayBuffer、postMessage 与
主线程 Canvas2D 之间选路,你不需要为降级写分支;root.mode 会告诉你实际选中了哪条。
配好 tsconfig.json 就能写 TSX:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@dopejs/pingo"
}
}function OrderRow({ index }: { index: number }) {
return (
<container width={480} height={32} padding={[6, 12, 6, 12]}>
<text value={`订单 #${index}`} fontSize={13} lineHeight={20} />
</container>
);
}完整入门见快速开始。
@dopejs/pingo-ui 提供 46 个与 shadcn/ui 对齐的组件,明暗主题、键盘导航与语义角色都
已接好,其中 Table / DataTable 自带虚拟滚动:
pnpm add @dopejs/pingo-ui它与引擎同版本发布。每个组件的用法、可用属性与已知缺口见 组件文档。
已经实现并由自动门禁覆盖的:
| 能力 | 说明 |
|---|---|
| 组件运行时 | TSX 函数组件、hooks 与 signal、memo、context |
| 样式 | 69 个 CSS 属性的版本化子集(当前 1.8.0),逐属性 feature bit |
| 布局 | flex 单行、position: absolute + inset、z-index、overflow |
| 虚拟滚动 | 窗口由核心规划,x/y 单轴,滚动帧不进入 Shell |
| 文本与编辑 | 引擎自绘文本、caret、选区、IME 组合、剪贴板、撤销重做 |
| 矢量 | SVG 路径与文档子集,图标可用 createSvg 直接接入 |
| 动画 | 核心内的 transition 与 keyframes,可 retarget/cancel,尊重减弱动效 |
| 无障碍 | 语义树随帧导出到旁路 DOM,键盘导航与角色贯穿组件库 |
| 降级链 | SharedArrayBuffer → postMessage → 主线程 Canvas2D |
目前没有:CSS 选择器与层叠的完整兼容、SSR 与 HTML 首屏、flex-wrap、渐变与图案
填充、图表。样式子集的逐条偏差见
样式支持表。
前置要求:Node.js 22.12+、pnpm 10.33.2、Rust 1.96.0,并安装 wasm32-unknown-unknown
target。
pnpm install --frozen-lockfile
pnpm check # 构建、lint、类型、测试、覆盖率与帧时基准
pnpm check:full # 加上协议/API/迁移/后端差分/动画/soak 等全部门禁
pnpm storybook:dev # 组件库展区技术决策以 docs/design.md 为准,交付顺序与门禁见
docs/plan.md。改架构或行为前先读 AGENTS.md。
真机帧时、真实输入法与跨浏览器矩阵属于平台资格认证,与工程门禁分离:未认证的平台
不对外宣称已达到对应指标,口径见 docs/m0-probes.md。
Apache License 2.0,自 0.3.0 起生效;v0.2.1 及以前的已发布版本继续适用其 原有的 MIT 许可证。
packages/ui 内联了少量 Lucide 图标路径(ISC),声明见
packages/ui/src/icons.ts。