Skip to content

pocket-stack/pocket-figma

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pocket Figma

A Figma file viewer for the Sony PSP and PS Vita.

Pocket Figma on a PSP at 59% zoom: the Paper Kit cover — a hand-drawn character asking 'I'm out of paper, got any?' — with the viewer HUD along the bottom

The Paper Wireframe Kit (Community) — 14,430 nodes, 2,293 component instances, hand-drawn Patrick Hand type, photos, masks — baked at compile time into streamed CLUT8 tile pyramids and panned with the analog nub at 60 fps on a 2004 handheld. No Figma runtime, no fonts, no network: the device never parses, it only consumes.

whole page at 8% one component at 100%
The Welcome page fit to the PSP screen The kit's calendar component at full zoom

Both frames are the executable's own 480×272 framebuffer, captured in the deterministic emulator the byte-exact tests run on. The full story — what actually lives inside a .fig, the overrideKey bug, the tile cooker, the streaming architecture — is in the blog post: Pocket Figma: Figma at 333 MHz.

Built on PocketJS and its deep-zoom engine layer (TILESET pak entries, loadTileTexture/freeTexture streaming ops, the <DeepZoom> component). pocket-figma is the first app in the pocket-<product> family; its pocket.json is the reference instance of the Pocket app manifest.

Controls

input action
Vita front touch: one finger pan, with inertial release
Vita front touch: two fingers pan and pinch to zoom
analog nub / left stick / d-pad pan
R / L trigger zoom in / out
△ / □ next / previous page
fit page
Nokia E7 E / Q zoom in / out
Nokia E7 T / S next / previous page
Nokia E7 Esc fit page

Page switching loops through all four baked canvases: Welcome, Components, Stickers, and Examples.

Build

bun run setup         # submodules + vendored deps
bun run bootstrap     # install the pinned PSP toolchain into the shared cache
bun run bake          # regenerate committed 1x + 2x tile pyramids from the .fig
bun run check:platforms  # validate the PSP baseline against PSP and Vita
bun run build         # dist/pocket-figma.js + .pak (bundle + baked tiles)
bun run psp -- -r     # dist/EBOOT.PBP — copy to ms0:/PSP/GAME/PocketFigma/
bun run vita -- -r    # dist/vita/PocketFigma.vpk — native 960x544 Vita build
bun run symbian       # dist/symbian/pocket-figma.sis — Nokia E7 / Belle
bun run symbian:guest # JS/PAK only; no Rust, GCCE, Docker, or device
bun run desktop       # run windowed via the vendored uihost (wgpu)
bun run golden        # byte-exact 960x544 controller/touch/fullscreen goldens
bun run e2e:vita      # build the VPK and compare native Vita3K captures

PSP builds resolve the normalized SDK in a fixed order: PSP_SDK, then PSPDEV, then Pocket's versioned shared cache at $XDG_CACHE_HOME/pocket-stack/psp/sdk/sdk-noabicalls-normalized-2026-06-19/mipsel-sony-psp (or the same path under ~/.cache). Both SDK environment variables are then exported to the build, so Rust and QuickJS cannot silently select different toolchains. The SDK, rust-psp, and quickjs-rs sources and exact revisions come from PocketJS's single toolchain manifest and the pocket-stack organization repositories. No DreamCart checkout is required.

The Vita target keeps PocketJS's 480×272 logical canvas while selecting the 512-pixel (@2x) version of each 256-logical-pixel tile. Layout, pan and zoom therefore stay identical to PSP, but Figma vectors, type and photos reach the native 960×544 display with twice the raster detail. Selection comes from platform.pixelRatio, not a Vita-specific branch. Physical buttons and the left stick map onto the same deterministic input contract as PSP. On Vita, front-panel contacts arrive in the same logical coordinate space: one finger directly pans with inertial release, while two fingers pan and pinch around their centroid. PSP keeps the complete controller fallback because touch is declared as an optional input.touch enhancement rather than a requirement. The release VPK has the stable Vita Title ID PFIG00001, so it installs as Pocket Figma alongside PocketJS demos and OpenStrike instead of replacing them. Its final package goes through PocketJS's shared Vita asset resolver: Pocket Figma's icon, 840×500 background, 280×158 startup image, and template overlay the framework defaults as one validated LiveArea contract.

The Symbian build uses PocketJS's isolated Nokia E7 toolchain and the same manifest-resolved guest. PSP and Vita retain the fixed 480×272 logical plan; the E7 starts at 640×360 and follows its 360×640 portrait viewport without remounting the DeepZoom state. The app id deterministically owns development UID 0xEEB7A533, executable PocketJsPocketFigmaEEB7A533.exe, and dist/symbian/pocket-figma.sis, so it installs alongside other PocketJS E7 apps. The pinned vendor/pocketjs revision contains the Symbian backend; POCKETJS_ROOT remains available only for testing a newer PocketJS checkout:

bun run check:platforms
bun run build
bun run symbian:guest
bun run test:symbian-package
bun run test:symbian-smoke

Vita builds expect VitaSDK (via $VITASDK, falling back to ~/vitasdk), cargo-vita, and the pinned Rust nightly in crates/pocket-figma-vita/rust-toolchain.toml. The native E2E command also expects Vita3K to have been launched once so it can clone a local config.yml; it uses its own VitaFS below out/ and never rewrites the emulator's normal configuration.

The baked tiles are committed: 5.9 MB at 1x and 15.7 MB at 2x across four pages. bun run bake regenerates both sets serially from a local copy of the .fig (--fig=<path>, defaults to ~/Downloads/Paper Wireframe Kit (Community).fig). The density-2 bake writes @2x.bin siblings and tiles@2x.ts without replacing the base pak.json. bun run cover regenerates the XMB and LiveArea art (ImageMagick is used for Vita's palette-PNG format): the icon is the Figma logo mark, drawn by the script itself; the backdrop is the kit's own cover, rendered from the .fig.

The PSP's XMB game menu on real hardware: the Pocket Figma icon selected over the wave background, with OpenStrike below

The result on a real PSP's game menu, screenshotted on the hardware itself. Real hardware needs custom firmware; PPSSPP runs the EBOOT as-is.

Layout

pocket.json          the Pocket app manifest (docs/manifest.md)
app/                 the viewer — main.tsx entry, app.tsx, baked tiles + manifest
tools/               fig.ts (.fig decoder/renderer) + gen-assets.ts (tile baker)
crates/              PSP EBOOT + PS Vita VPK bins (embed the same bundle + pak)
scripts/             psp.ts / vita.ts / desktop.ts build drivers
docs/                manifest spec + the screenshots above
art/                 ICON0 / PIC1 (generated by tools/gen-cover.ts)
vendor/              pocketjs · rust-psp · quickjs-rs submodules

Credits

  • Paper Wireframe Kit by Method (Tyler Sharpe & Claire Lorman), Figma Community, CC BY 4.0. The kit is rendered from its own file's derived geometry; the .fig itself is not redistributed here.
  • The .fig container is decoded with kiwi, Evan Wallace's schema format — reading his file format with his own tools felt right.
  • Figma and the Figma logo are trademarks of Figma, Inc. Pocket Figma is an unofficial community project, not affiliated with or endorsed by Figma.

MIT.

About

A Figma file viewer for the Sony PSP — a real Community file baked into streamed CLUT8 tile pyramids, panned with the analog nub at 60 fps. The first pocket-<product> app.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages