2011 · Handheld console · Sony Computer Entertainment

Sony PlayStation Vita

Twice the pixels, zero forks. The same bundles, byte-exact goldens at density 2.

Registered targetGuest · QuickJS + native corehosts/vita/

The Vita paired a quad-core Cortex-A9 with a PowerVR SGX543MP4+, 512 MB of RAM and a 5-inch 960×544 OLED, plus a capacitive touchscreen and a rear touch pad. It launched in Japan in December 2011 and was discontinued in 2019.

For PocketJS the Vita is the second profile of one application contract: the logical viewport stays 480×272, the profile sets raster density 2, and the same manifest resolves unchanged. It is also the reference for the GXM path of the Pocket3D cores.

Processor
Cortex-A9 ×4 · 333 MHz
Memory
512 MB + 128 MB VRAM
Display
960 × 544 OLED
A PlayStation Vita PCH-1100 (first-generation OLED model), front view
A PlayStation Vita PCH-1100 (first-generation OLED model), front view. Photo: Evan-Amos · Public domain
01

Hardware

curated here · sources below

Compute

CPU
ARM Cortex-A9 MPCore, 4 cores
Clock
333 MHz nominal, 444 MHz available to titles Sony never published the clock; the SoC tops out at 500 MHz
GPU
PowerVR SGX543MP4+, 4 cores
RAM
512 MB system + 128 MB video

Display & input

Display
5″ OLED, 960 × 544 (qHD), 220 ppi PCH-2000 uses a 5″ LCD of the same resolution
Touch
Capacitive multi-touch front panel, rear touch pad
Input
D-pad, two analog sticks, △ ○ ✕ □, L/R, Start/Select, PS
Sensors
3-axis gyroscope, 3-axis accelerometer, compass, two 0.3 MP cameras

Storage & connectivity

Media
PS Vita game card, proprietary memory card 4–64 GB PCH-2000 adds 1 GB internal
Connectivity
Wi-Fi 802.11b/g/n, Bluetooth 2.1+EDR, optional 3G
Battery
2210 mAh

Body

Dimensions
182 × 83.5 × 18.6 mm (PCH-1000)
Weight
260 g Wi-Fi · 279 g 3G
Released
17 December 2011 (Japan) · 22 February 2012 (NA/EU)
System software
LiveArea; homebrew via HENkaku / VitaShell
02

PocketJS on this machine

Guest · QuickJS + native core

What runs

pocketjs-vita embeds QuickJS, feeds the normal PocketJS pak and renders the standard DrawList with vita2d/GXM. The JS/pak pair is recompiled from the resolved Vita plan so density and host-contract constants are target-correct; each manifest id becomes a stable nine-character title id, and every VPK carries complete LiveArea artwork.

What is proven

Real-hardware install, boot, GXM presentation, controller and interactive flows; a Vita3K-driven 960×544 CPU pixel oracle plus GXM texture/font residency checks in the e2e suite.

Record

  1. v0.4.0

    PS Vita becomes a first-class target: native-density rendering, touch, VPK packaging, Vita goldens.

  2. v0.7.0

    Vita renders Pocket3D worlds through GXM instead of the CPU blitter.

  3. v0.8.0

    The Cover Flow launcher ports to Vita; the svc mailbox goes wireless.

Target profile · production registrycontracts/spec/platforms.ts
Registry key
vita
Host ABI
2
Platform
vita
Form
takeover
Physical viewport
960 × 544
Logical viewports
480 × 272
Presentations
integer-fit
Raster density
Capabilities
  • input.analog.left
  • input.buttons
  • input.cursor
  • input.touch
  • text.glyphs.baked

Acquisition reports

04

Example code

upstream source · highlighted at build time
hosts/vita/rust-toolchain.tomltoml · 3 lines · @6c43f49

The pinned nightly recorded next to the host.

[toolchain]
channel = "nightly-2026-05-28"
components = ["rust-src"]
05

Bring-up guide

upstream documents · rendered verbatim

Toolchain, build, deploy and acceptance are owned by pocket-stack/pocketjs. The documents below are rendered from the pinned checkout without edits; relative links point back into the repository at the same revision.

PocketJS for PS Vita

4 min read · 861 words

VitaSDK + cargo-vita + Rust nightly; build, install with VitaShell, golden E2E.

rendered verbatim fromhosts/vita/README.md@ 6c43f49raw ↗

pocketjs-vita is the native PS Vita host for PocketJS. It embeds QuickJS, feeds the normal PocketJS pak, renders the standard DrawList with vita2d/GXM, and reads the physical Vita controller. Applications do not need a Vita-specific entry point, but their JS/pak pair is recompiled from the resolved Vita plan so density and host-contract constants are target-correct.

The PocketJS logical viewport remains 480x272, so PSP applications keep the same layout. The resolved Vita profile separately sets a 960x544 physical viewport and raster density 2: geometry is sampled at physical resolution, font coverage/SVG/core masks are baked at 2x, and @2x image or raw-pak siblings are selected when present. There is no letterboxing or aspect-ratio crop. Native Rust hosts can read the d-pad, face buttons, shoulders, and both analog sticks through input::read. The stock PocketJS frame ABI deliberately forwards buttons, the left stick, and front-panel contacts through Runtime::frame_with_input; the public capability is input.analog.left. The front panel is sampled once per frame and exposed to applications as stable contact ids in 480x272 logical coordinates through touches() from @pocketjs/framework/input.

Toolchain

The supported local setup is:

  • VitaSDK in $VITASDK (this workstation uses ~/vitasdk)
  • cargo-vita 0.2.2
  • Rust nightly 2026-05-28 with rust-src
  • Vita3K for emulator E2E

tools/vita.ts prepends VitaSDK and the rustup shims to PATH, so a Homebrew stable Rust installation cannot accidentally take over a Vita build. The pinned toolchain is also recorded in rust-toolchain.toml.

export VITASDK="$HOME/vitasdk"
export PATH="$VITASDK/bin:$HOME/.cargo/bin:$PATH"

bun play vita hero
# builds, installs the hero's stable title id, and launches Vita3K
bun play vita gallery --fullscreen
# also enters host fullscreen and stretches the Vita display to fill it
bun play --help
# lists every demo accepted by the command

# Low-level build only:
bun run vita hero --release
# dist/vita/hero-main.vpk

# Cover Flow launcher + every Vita-admitted Pocket app in one VPK:
bun run launcher:vita --release
# dist/vita/launcher-main.vpk

bun play vita <demo> owns the interactive loop: it builds the selected demo, validates and installs the VPK, safely restarts an existing Vita3K instance, then checks that the new emulator process survives startup. In Vita3K, use the arrow keys for the d-pad, Q/E for L/R, C for Circle, X for Cross, V for Triangle, Z for Square, WASD/IJKL for the two sticks, and F11 to toggle fullscreen.

The VPK uses vita2d's precompiled shaders and does not require libshacccg.suprx. Vita3K's normal interactive setup should still install the official PS Vita firmware; the isolated homebrew E2E deliberately runs HLE modules only so it cannot mutate a developer's normal VitaFS.

Install on a PS Vita

Build the release VPK with the command above, then install it directly with VitaShell; Vita Toolbox is not required:

  1. Open VitaShell and press SELECT to start its configured USB or FTP connection.
  2. Copy the named artifact, such as dist/vita/hero-main.vpk, to a writable location such as ux0:/data/hero-main.vpk.
  3. Stop the transfer, select the VPK in VitaShell, press X, and confirm the install prompt.
  4. Return to LiveArea and launch the demo's named bubble.

Each manifest's stable reverse-DNS id is encoded by the Vita backend as P plus the first eight uppercase hexadecimal digits of its SHA-256 digest. This produces a valid nine-character Vita title id without a per-demo table, so Hero, Gallery, and other demos coexist instead of replacing one another. Keep the manifest id unchanged across releases to preserve installation identity. Every VPK also includes PocketJS's black 128x128 bubble icon and complete LiveArea artwork (840x500 background, 280x158 startup image, and template), so a new app never installs as a blank white bubble or generic launch gate. Custom hosts call packageVitaVpk() from @pocketjs/framework/vita-package: framework defaults are resolved first and application artwork overlays them. The VPK is self-contained; no separate app pak, artwork, or shader file is needed.

Reusable Rust hosts that replace one Pocket guest with another must consume the old runtime with Runtime::shutdown(self) after presenting a closed scene. That boundary releases QuickJS, waits for GXM, retires the guest's texture/font handles, drops its Ui, and uninstalls its pak. Plain Drop only releases QuickJS so it remains safe inside a host-owned open scene; it does not authorize constructing a second guest.

Golden E2E

bun run e2e:vita
E2E_VITA3K_APP=hero bun run e2e:vita  # focused iteration

For each demo the driver builds a capture VPK, boots it in an isolated VitaFS, waits for the guest done marker, and terminates only the spawned emulator. It checks that every guest frame is exactly 960x544, was rasterized directly at physical resolution, contains real detail inside at least one 2x2 logical block, and is byte-identical to its independent tests/goldens/vita image. Vita3K's GXM framebuffer cannot currently be read back coherently on macOS, so the pixel oracle is CPU-rendered; each capture also asserts that every DrawList texture and font atlas used by the production GXM pass is resident in its GPU cache. This catches backend-only omissions such as core-generated rounded-corner textures or a font atlas rejected by the Vita texture packer.

Current Vita3K 0.2.1 builds on macOS can fault while tearing down GXM after a guest calls sceKernelExitProcess. Capture builds therefore park after the done marker and let the host driver own process termination. Production VPKs are unaffected.

Photo

Wikimedia Commons · PlayStation-Vita-1101-FL.jpg — Evan-Amos, Public domain.