为什么要让 Vue 跑在 PSP 上?——与 PocketJS 团队的一个夜晚
在 RustChinaConf 听完半糖关于原生 Rust UI 的分享后,我认识了 PocketJS 的开发者。一次从怀疑到理解的谈话,让我重新思考老设备、极致约束和技术探索的价值。
2026 年 10 月 16 日,RustChinaConf 的第一天。下午最后一场演讲结束时,我没想到自己接下来会和几位刚认识的开发者一起吃火锅,在深圳蛇口的海边散步,更没想到,一次原本只是出于好奇的交谈,会让我重新理解一个项目为什么值得做。
那场演讲叫《不需要 JavaScript 的 Vue:Rust 嵌入式 UI 新探索》,讲者是半糖。她的出场很特别,也是我这次大会印象最深的讲者之一:漂亮、优雅,演讲内容却又十分硬核。用熟悉的 Vue 语法来描述界面,最后生成可以运行在受限硬件上的原生 Rust 程序。这个想法本身就很吸引我。
演讲结束后,我没有立刻离开。我走到他们附近,先听其他参会者继续追问技术问题。等大家聊得差不多了,我才开口介绍自己:我是做游戏开发的,两年前曾用 Rust 和 Bevy 做过一个体素沙盒游戏 Demo,现在主要做 Unity 开发。
没想到,PocketJS 的创始人雪碧似乎对这件事颇有兴趣。我们聊起那个由程序生成、可以自由修改的体素世界,也聊到有没有可能把这样的东西移植到 PocketJS 所面向的设备上。那时还只是一个有趣的设想,但它一下子拉近了我们的距离。后来,我们越聊越投机。
1一个让我好奇,也让我不解的项目
PocketJS 想做的事情有点反常识:让现代的前端组件开发体验,出现在 PSP 这样二十多年前的设备上。
如今做一个小程序或桌面工具,使用浏览器内核似乎再正常不过。开发者习惯了 HTML、CSS、JavaScript,习惯了 Web 框架完整而强大的生态。于是一个功能很简单的界面,也可能需要相当庞大的运行时来承载。
我以前用过一些老手机,对这种代价有直接的感受:一个原本应该轻巧的页面,打开却很慢,操作不跟手,内存和资源消耗也不小。我总觉得这里面有某种不协调——为了实现很简单的交互,似乎付出了远超需要的成本。
PocketJS 则走向另一个极端。它不试图把完整的浏览器塞进掌机,而是把现代前端里有用的组件模型、响应式状态和声明式编写体验留下,把昂贵的浏览器设施拆掉,重新安排各层的工作。
官方介绍中,以 2004 年推出的 Sony PSP 为代表的演示,可以在约 8 MB 的应用内存预算里运行带动画的现代组件 UI,并以 60 FPS 为目标交付了实际效果。这里的 8 MB 指运行预算,并不是说整台 PSP 只有 8 MB 内存。1
可是,我一开始真正不理解的不是它怎么做到,而是:
为什么一定要做到这种程度?
如果未来的硬件越来越快,内存越来越大,为什么还要耗费那么多精力,让一个 UI 框架去适应早已停产的设备?就算技术上很厉害,这会有多少用户?有多少商业价值?难道只是在满足一种怀旧情绪吗?
2Vue 是怎样离开浏览器的
在与雪碧交流之后,我又回头看了 PocketJS 的技术资料,才逐渐把它的架构拼起来。
首先,PocketJS 并不等于“所有模式都不需要 JavaScript”。这是我认为最容易误解的一点。
它的常规方案允许开发者使用 Solid、Vue Vapor 等组件框架,经过构建后由设备上的 QuickJS 执行 JavaScript;但界面并不交给浏览器 DOM 渲染。JavaScript 负责组件状态与逻辑,通过精简的操作接口更新原生 UI 树。真正的布局、文字、动画和绘制,由一个以 Rust 编写、面向多个平台的核心负责。2
而半糖演讲中更激进的方向,是 MicroTS 的 AOT 编译路线:将受支持的 Vue 单文件组件及 TypeScript 代码经过分析与转换,生成 Rust 代码,让原生构建可以在不运行 JavaScript 引擎的情况下驱动同一套 UI 核心。它还不是“任意 Vue 项目都可以直接编译成 Rust”,而是一套有明确语法和能力边界的探索。3
两条路径可以简单概括为:
- 常规运行时:Vue / Solid → JavaScript → QuickJS → Rust UI Core → 设备图形后端。
- 原生 AOT:受支持的 Vue / TypeScript → MicroTS → Rust → Rust UI Core → 设备图形后端。
真正打动我的不是“用 Rust 重写了 Vue”,而是这个更精巧的分工:保留人喜欢的开发方式,重新设计机器为它付出的成本。
为了适应这些设备,PocketJS 还把很多原本发生在运行时的工作提前到了构建期。例如,一部分样式会预编译成可直接查表的记录,字体字形可以预先烘焙;不同设备只需要实现相应的平台后端,而不必各自重写一套布局和状态系统。2
这让我联想到游戏引擎里的资源 Cook、预生成网格、离线光照和平台专用资源格式。开发时保留灵活性,发布时尽可能减少运行时的不确定性。不同领域,背后却有相似的思想。
3为什么偏偏是老设备?
晚饭时,我把这个疑问直接告诉雪碧。
我原先想,或许给现代芯片装上复古外壳的新掌机更适合作为目标:性能更强,开发更方便,未来也更容易普及。但雪碧的解释,让我改变了看法。
首先,那些真正的老设备早已进入过许多人的生活。PSP、旧 iPod 等名字,不需要再向大家解释一遍。它们有历史,有记忆,也有辨识度。“现代 Vue 跑在 PSP 上”,就是一个让人立刻想追问“怎么可能”的故事。
相比之下,一台新生产的复古设备,可能只是换了外壳的现代计算机。它当然也有自己的价值,却未必能像真正的旧硬件那样直观地证明一个技术系统有多轻。
其次,老设备不一定更难接近。雪碧提到,一些二手旧设备的价格其实很低,有些几十元就能找到;而新出的复古掌机可能反倒更贵。对于只是好奇、想试试的人,甚至不必先买硬件,可以从浏览器中的演示体验开始,再决定是否寻找实体设备。
最后,他们真正感兴趣的,本来就是让软件回到那些有趣的机器上。不是为了迎合下一代芯片的性能增长,而是看看那些早已被主流软件生态抛下的设备,还能焕发出怎样的可能性。
我听完突然觉得,这个选择并不离奇。恰恰相反,它非常明确,而且比“适配所有新硬件”更有自己的性格。
我原先用软件市场和商业规模来衡量这个目标,但雪碧讨论的是技术、传播、设备文化和创作乐趣的结合。他不一定要证明旧设备有多大的新市场,才有理由让它们重新运行有趣的软件。
4极端的约束,反而能逼出新的方法
之后我读到雪碧在 PocketJS 官方介绍里写的一句话:
The PSP is the proof, not the point.
PSP 是一种证明,而不只是目的地。1
这句话和晚上的交流放在一起看,格外有意思。
现代电脑的资源太充裕了。一次不必要的对象分配,一套过重的 UI 抽象,多一次渲染阶段,或许都能被更快的 CPU 和更大的内存悄悄吞掉。程序照样运行,开发者甚至没有动力意识到问题。
而 PSP 不会替你掩饰。它要求你认真计算内存、绘制调用、数据传输、布局和每一帧的开销。约束不是单纯的阻碍,它也像一把尺子,迫使设计接受检验。
我想,这也是极致项目特别吸引我的原因。它不是单纯地把某个指标卷到极限,而是通过一个几乎苛刻的目标,逼迫自己找到更清楚的系统边界。
PocketJS 为旧设备设计出的许多能力——轻量级原生 UI、编译期处理、跨平台核心、可验证的渲染结果——理论上也可能在桌面工具、嵌入式系统、游戏编辑器等地方发挥作用。它们能否直接复用,需要具体工程去验证,但这些技术积累并不会因为 PSP 停产就自动失去意义。
我还想起数学里的挂谷问题:一根长度固定的针,怎样在尽可能小的平面区域里旋转半周?乍看之下,谁会在现实生活里需要这么做?但沿着这个貌似无用的问题,数学家们却发展出许多更深的研究方向。
这当然不是说“做一件很难的事情,就必然产生伟大的成果”。只是我越来越觉得:问题本身的直接用途,不应该是衡量探索价值的唯一尺度。
有些技术不是先有商业需求才值得研究。相反,正是因为有人执着于一个特别的目标,我们后来才获得了原本想象不到的工具。
5从我的体素世界,聊到他们的掌机世界
我自己也做过一个这样的项目。
两年前,我用 Rust 和 Bevy 开发体素沙盒游戏。它并不以堆砌大量美术资产为特点,而是尝试利用程序化生成,让世界可以被修改、重组,并保持很高的自由度。
这种目标也带来不少麻烦。我曾为引擎架构、数据组织、编译时间和迭代效率感到痛苦,甚至在很长一段时间里没有继续开发。可我始终觉得,一个可以自由改变、持续演化的体素世界,是很酷的东西。
所以当雪碧听到我的经历,提起或许可以尝试将这个方向带到 PocketJS 支持的设备上时,我一下子来了兴趣。
当然,这不意味着原来的 Bevy 项目可以直接打包到 PSP 上。那可能需要重新考虑渲染、世界规模、数据表达甚至整个运行时。但也正因为如此,它才有趣:如果资源极其有限,一个体素世界最小需要保留什么,才能让人仍然感到自由?
这让我想起 PocketJS 团队已经做过的 Pocket Voxel:他们把原本运行在桌面环境中的游戏逻辑和体素化场景,改造成由 TypeScript 处理玩法、Rust 处理渲染的形式,并让它在 PSP 上运行。它既展示了掌机的限制,也展示了移植并不等于原样搬运——有时需要重新设计整个工作分工。4
那晚的讨论没有定下任何合作计划。但一个长期被我搁置的项目,突然又被另一个人的好奇心照亮了一点。这种感觉很奇妙。
6火锅、海边,和几位很酷的开发者
原本我以为,演讲结束后能加个微信就已经很幸运了。没想到我们后来竟然一起吃了火锅,又去了蛇口海上世界文化艺术中心一带,沿着海边走了走。
那天认识的三位开发者,是半糖、雪碧和 Jimmy。
半糖的演讲非常精彩。她把一个听起来有些不可思议的方向,讲成了可以认真理解的编译器和系统工程问题。她在舞台上的样子很漂亮、很优雅,但更让我敬佩的是,她确实深入参与着这样一个既小众又硬核的技术项目。
雪碧聊了不少以前的经历。他做过多年偏图形和渲染的前端开发,接触过 Three.js 一类技术,也聊起 AFFiNE 和后来创业、做自己感兴趣的项目的过程。他给我讲了 PocketJS 背后的取舍,还分享了很多关于 AI 辅助开发的经验。比起单纯介绍一个产品,我更像是在听一个开发者解释:自己为什么愿意把时间投入到这样一件事上。
Jimmy 则做编译器相关的工作,之前还在 JetBrains 实习过。我们聊到编程语言,我问他最满意的是哪一门。他一开始说其实没有;被我追问如果非得选一个,他最后选了 Kotlin。我也一直很欣赏 Kotlin,于是又多了一个共同话题。
他们都非常友善。我们没有一直拘泥于技术演讲上的那些正式问答,而是自然地聊项目、聊语言、聊职业经历,也聊一些没有明确答案的想法。
我忽然发现,这样的交流对我来说特别珍贵。过去我更多是在电脑前阅读项目、研究代码、看别人的 GitHub。那些厉害的开源作者,往往只是一个头像、一段简介和一长串提交记录。
而今晚,我们就在同一张桌子上吃火锅,随后一起走到海边。一个项目不再只是 README 和架构图,它背后有具体的人,有他们的审美、经历和选择。
7我终于理解了一点
回到最初的问题:为什么要让 Vue 跑在二十多年前的 PSP 上?
如果只从商业化和目标设备的用户规模来看,我依然觉得这是一个很有风险、很小众的方向。技术极致不自动等于市场成功,怀旧也不能替代长期可持续的产品需求。
但我现在不再认为,这个问题一定需要一个商业上的答案。
PocketJS 有很明确的技术追求:把现代组件式 UI 的开发便利,与轻量、确定、跨平台的原生运行时结合起来。旧硬件让这种追求变得可以被检验,也让成果变得有趣、直观、有故事。
而对于做项目的人,选择一个自己真正热爱的、足够鲜明的目标,或许本身就是很重要的创造力来源。
我喜欢这种态度。不为了一味追赶硬件性能,也不为了给旧设备强行寻找宏大的市场理由,而是认真地把一个特别的想法做到极致。在实现它的过程中,新的技术、新的经验,甚至新的用途,才有机会逐渐出现。
今晚我原本只是想听一场关于 Rust UI 的演讲。后来我认识了几位很棒的开发者,吃了一顿愉快的火锅,沿着海边走了一段路,也重新理解了一个曾让我困惑的开源项目。
我想,这比单纯记住 PocketJS 用了哪些技术,更值得写下来。
注释
-
Yifeng “Evan” Wang,Introducing PocketJS,2026 年 7 月 6 日。项目作者介绍 PSP 目标设备、约 8 MB 的应用预算、60 FPS 演示及设计动机;本文的现场交流与主观体会来自作者本人。 ↩ ↩2
-
PocketJS 官方文档,Architecture 和 Overview。说明 QuickJS 常规路径、Rust 原生 UI Core、预编译样式与平台后端。 ↩ ↩2
-
PocketJS 官方仓库,MicroTS / Ahead-of-time compilation。说明受支持的 Vue SFC / Solid TSX 和部分 TypeScript 模型可以编译为 Rust;它与常规 JavaScript Guest 路线有所不同。 ↩
-
Yifeng “Evan” Wang,Pocket Voxel: A Creature-RPG From First Principles,2026 年 8 月 7 日。项目作者记录了将 TypeScript 游戏逻辑与 Rust 体素渲染移植到 PSP 的过程及实际硬件约束。 ↩
CONTINUE EXPLORING