pocket-stack/pocketjs
GitHub: pocket-stack/pocketjs
PocketJS 是一个在浏览器外运行的轻量级 JSX UI 框架,通过 Rust 核心实现原生硬件渲染,在 8 MB 内存预算下达成 60 FPS 动画,支持 Solid 和 Vue Vapor 组件语法。
Stars: 490 | Forks: 18
PocketJS
[](https://www.npmjs.com/package/@pocketjs/framework)
[](https://www.npmjs.com/package/@pocketjs/cli)
[](./LICENSE)
[](https://discord.gg/cTce4eXzSK)
浏览器外的高性能 JSX UI,支持原生渲染、标准
Vue Vapor 和 Solid 支持、Tailwind 设计系统,并在 8 MB 内存预算下实现 60 FPS 动画。
编写 Solid 或 Vue Vapor 组件,在 QuickJS 上运行,让 PocketJS 将布局、样式、文本和动画转移到微型的 `no_std` Rust 核心中。
它可以在真实的 PSP 硬件、PPSSPP、浏览器(WASM)、原生 macOS 窗口(wgpu)以及无头 Bun 上运行。完整的设计与契约:
[DESIGN.md](./DESIGN.md)。PocketJS 正在发展成为一个专门运行时的家族——Rust 核心、规范固定的接口表面、单一 QuickJS guest——相关文档记录在
[RUNTIMES.md](./RUNTIMES.md) 中;3D 基础位于
[pocket3d/](./pocket3d/) 中,其首个游戏运行时为
[OpenStrike](https://github.com/pocket-stack/open-strike)。
## 截图
https://github.com/user-attachments/assets/dbbf656f-a3b2-411d-ab52-fece6a10f68a
这些 PocketJS UI 在 8 MB 内存预算内的 Sony PSP 上以 60 FPS 流畅运行,包括动画过渡和输入反馈。
| 画廊 | 设置 |
| --- | --- |
|  |  |
| **运动实验室 — 烘焙的关键帧时间线** | **运动实验室 — 3D pipeline** |
|  |  |
## 快速开始
```
bun install
bun scripts/build.ts hero # -> dist/hero.js + dist/hero.pak
bun scripts/build.ts hero-vue-vapor-main --framework=vue-vapor
```
或者通过 [`pocket` CLI](https://www.npmjs.com/package/@pocketjs/cli) 驱动一切:
`npm i -g @pocketjs/cli`,然后运行 `pocket doctor` 检查 bun / Rust / PSP
工具链(`pocket setup` 会安装缺失的部分),`pocket create
`
用于生成应用脚手架,而 `pocket dev|build|psp|hw|psplink` 封装了下面
的脚本。
构建分为两个阶段:第一阶段对从入口可达的每个模块进行 babel 转换(特定于框架的 JSX + TypeScript,在 `.cache/` 中进行内容哈希缓存),同时从 AST 中收集类字符串和文本码位;然后
Tailwind 编译器写入 `styles.bin` 和 `src/styles.generated.ts`,字体
烘焙器会为你的应用恰好使用的字符光栅化 Inter atlas 插槽,
所有内容都会被打包进 `dist/.pak` 中。第二阶段使用 Bun
(iife,未压缩)从缓存的转换结果中打包。
```
import { createSignal } from "solid-js";
import { Text, View } from "@pocketjs/framework/components";
export default function Counter() {
const [count, setCount] = createSignal(0);
return (
Count: {count()}
setCount(count() + 1)}
/>
);
}
```
挂载入口看起来应该像普通的应用引导代码;框架
会处理宿主检测、生成的样式表、pak 图像上传以及
宿主帧回调:
```
import { mount } from "@pocketjs/framework";
import App from "./app.tsx";
mount(() => );
```
样式规则(编译时,没有运行时 CSS):当且仅当类字面量中的
*每个* token 都是受支持的 utility 时,该字面量才会被编译(参见 DESIGN.md 中的 "Tailwind subset (v1)");
动态样式是完整字面量的三元表达式、`style={{...}}` 或
`animate()`。
`classList`、`hover:` 和模板插值类会导致编译错误。
`rounded-full` 要求在同一个字面量中包含 `w-N h-N`。
框架选择是显式的:在 `pocket.config.ts` 中设置 `framework: "solid"` 或
`framework: "vue-vapor"`,或者向 `scripts/build.ts`、
`scripts/dev.ts` 或 `scripts/psp.ts` 传递 `--framework=...`。应用状态和
组件生命周期来自于原生框架包(`solid-js` 或 `vue`);
PocketJS 提供宿主组件、输入、动画、资产和原生
运行时连接。
`@pocketjs/framework/components` 还暴露了小型 app-shell 原语:
`Screen`、`Focusable`、`FocusScope`、`ActionHandler`、`FocusGrid`、`Portal`、
`Modal` 和 `ActionBar`。`FocusGrid` 为子树提供了当前明确的行/列 d-pad 遍历;
以后虚拟化网格也可以位于相同的焦点契约之后。
`Portal` 挂载到运行时覆盖层根节点,因此模态/操作栏 UI
永远不会参与到当前活动屏幕的 flex 布局中。`Modal` 拥有焦点
作用域,并在保持帧动画生命周期回调运行的同时,阻止后台按钮处理程序;
路由切换仍然是普通的应用状态,而非必需的路由包。
## 命令
```
bun run test # spec contract + tailwind parser tests
bun scripts/build.ts [--framework=solid|vue-vapor] [--extra-chars=…]
bun run psp / bun run dev / bun run wasm # EBOOT / web host / wasm core
bun psplink # interactive real PSP switcher over PSPLINK
bun run hw hero --trace # real PSP via PSPLINK + host0 trace
bunx tsc --noEmit # typecheck (babel owns the JSX transform)
```
## DevTools + 时间旅行
Pocket DevTools([DEVTOOLS.md](DEVTOOLS.md))内置于每个 bundle 中:一个
带有语义名称(`debugName` / ``)的组件树,在**设备屏幕上**(包括真实的 PSP,通过 PSPLINK USB 线缆)悬停高亮,暂停/单步执行,REPL,来自硬件的 `console.log`,以及常驻的
输入流飞行记录仪——会话能够逐字节精确重放,因为整个
运行时是固定 dt 确定性的。
```
bun run devtools # panel + hub + USB bridge, one process
bun run devtools cards # + build, link and launch cards on a real PSP
bun run tape replay --png 60 # render any frame headlessly
bun run tape:check # session-golden replay regression
```
按需设备截图(面板中的 📷)在所有宿主上均可用——在真实的
硬件上,原始 VRAM 通过 usbhostfs 挂载传输,网桥在桌面端对 PNG 进行编码。
## 确定性 + 模拟宿主
时间是帧计数器,而非挂钟时间([DETERMINISM.md](DETERMINISM.md)):
虚拟时钟(`@pocketjs/framework/clock`)将模拟速率作为一种
宿主策略(web 宿主上的 `?hz=2` 会在真实屏幕上运行 2 FPS 的世界),
effect shell(`@pocketjs/framework/effects`)将异步结果量化到
帧边界上,而无头模拟宿主(`host-sim/`)会将脚本化的
用户旅程重放为逐字节精确的逐帧像素轨迹——`test/sim.test.ts` 是
证明,`scripts/flake-lab.ts` 是挂钟时间对照实验。
字体:Inter(OFL),内置在 `assets/fonts/` 中。标签:QuickJS, Rust, Solid/Vue前端, 信息收集, 可视化界面, 嵌入式开发, 数据可视化, 硬件渲染, 网络流量审计, 自动化攻击, 跨端UI框架