Skip to content
Phoenixx1202Public

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

PS4 React

ReactPS4

React + JSX runtime for PlayStation 4 homebrew. It renders a real React tree through Embedded React, runs JavaScript on QuickJS and presents a 1920×1080 framebuffer with sceVideoOut — no OpenGL or shader compilation.

The default build produces a single installable package: PS4-React-Starter.pkg.

Features

  • 1920×1080 presentation with two linear VideoOut buffers and vsync pacing.
  • React 18 + JSX/TSX bundled with esbuild and executed by QuickJS.
  • Controller input (D-pad, sticks, Cross/Circle, L1/R1, L2/R2, Options).
  • Audio through sceAudioOut (48 kHz stereo) and a real-time mixer.
  • Networking with libcurl + mbedTLS: Http requests and Downloads.
  • Remote images (PNG/JPEG) with an in-memory and disk cache.
  • Archives (ZIP, TAR, 7z) through libarchive, with ZIP/TAR creation, extraction and inspection.
  • Runtime text shaping for CJK, Arabic and Indic scripts with HarfBuzz and SheenBidi; apps package only the Noto fonts they use.
  • Native filesystem under /app0, /data and /download0.
  • PKG installation and removal through the BGFT install service via Packages.install/Packages.uninstall, with progress and errors. Apps that use it are packaged with "privileged": true (IV0000/gde).
  • Payload delivery to GoldHEN's BinLoader with ELF and size checks.
  • Server-Sent Events through Sse.connect with bounded event queues.
  • WebSocket text client (ws:///wss://) with polling, ping/pong and close.
  • Music playback: MP3 and OGG Vorbis decoding, 48 kHz resampling, local files and HTTP(S) streams, ID3/Vorbis metadata, MP3/OGG album art, playlists and crossfade on the mixer's two music decks.
  • Video playback through sceAvPlayer (local MP4/H.264 + AAC, NV12 with pitch/crop, ARGB blit at 30 fps for 480p, audio through the mixer on a dedicated thread). 720p/1080p and the GPU texture path are pending.
  • GPU presentation through Piglet/OpenGL ES ("gpu": true) using Sony's precompiled texmap shaders, with the software VideoOut path as fallback. An opt-in Vulkan/RADV build (PS4SX2 SDK) hosts the complete React runtime and presents the UI at 1080p60 through a Vulkan texture; video frames are uploaded as Y/UV textures and composed on the GPU.
  • Multi-controller input with one pad per logged-in user and useGamepad(playerIndex); any pad navigates the UI.
  • Device information (model, firmware, CPU frequency/temperature, SoC temperature, free flexible memory) and user enumeration.
  • Save data through sceSaveData and the system on-screen keyboard through sceImeDialog.
  • PKG packaging validated with PkgTool.Core and a load-image checker.
  • Dev hot reload over TCP when the build enables -DPS4_REACT_DEV_SERVER=ON.

Roadmap

See ROADMAP.md for the implementation plan, current status and checklist.

Requirements

Building on Windows uses WSL2 and a PacBrew rootfs with the OpenOrbis toolchain and runtime libraries. The same steps work on Linux with the toolchain installed.

  • Windows 10/11 + WSL2 (Ubuntu 22.04/24.04), or Linux.
  • PacBrew rootfs containing:
    • OpenOrbis PS4 toolchain (clang, create-fself, create-gp4, PkgTool.Core);
    • runtime libraries: libcurl, mbedTLS, libarchive, bzip2, zlib, libpng;
    • HarfBuzz 14.6 source at /workspace/harfbuzz (the Linux/CI build downloads it automatically).
  • Node.js 20+ and npm.
  • Python 3, CMake, Git, curl, xz.

The first build fetches QuickJS-ng 0.15.0 and Embedded React at the revision in dependencies.lock.json, applies the pinned engine patches and builds HarfBuzz for the PS4.

Build

.\tools\build_ps4.ps1

On Linux, use the shell entry point:

./tools/build_ps4.sh

Output:

build/PS4-React-Starter.pkg

The command builds only that package. -NoPackage produces the ELF/SELF without packaging. -DevServer enables the TCP hot-reload receiver for local development. The GitHub Actions workflow is .github/workflows/build.yml.

Samples

samples/ contains small apps for the native APIs. Build one with:

.\tools\build_ps4.ps1 -Sample counter
# -> build/PS4-React-counter.pkg

On Linux, build one sample with:

./tools/build_ps4.sh --sample counter

Build every sample into samples-pkg/:

.\tools\build_samples.ps1
./tools/build_samples.sh

Each sample's app.json supplies its title and Title ID. See samples/README.md for the list and ideas.

Development and hot reload

Install a development build on the console with the receiver enabled:

.\tools\build_ps4.ps1 -DevServer
./tools/build_ps4.sh --dev-server

Then, on the workstation, point the watcher at the console's IP:

node tools/dev_server.mjs --host 192.168.1.50
# sample:
node tools/dev_server.mjs --host 192.168.1.50 --sample counter

The console listens on TCP port 9001, validates each ERHR frame with CRC-32 and reloads the JavaScript bundle in the running title. Assets (images, fonts, sounds) are still compiled into the PKG; rebuild and reinstall when they change. The receiver is off in release builds.

Install

  1. Copy PS4-React-Starter.pkg to a USB drive or /data/pkg.
  2. On the PS4, open GoldHEN → Install Package and select the file.
  3. Launch PS4 React Starter.

Title ID: CUSA99059.

The runtime log is written to /data/PS4React/react.log (fallback /temp0).

Controls

Input Action
D-pad / left stick Move focus
Cross Confirm
Circle Back
L1 / R1 Previous / next page
L2 / R2 Previous / next section
L3 / R3 / touchpad Exposed as actions
Options Exit

Native APIs

JavaScript reaches the host through @ps4-react/core.

API Purpose
Http.request HTTP/HTTPS request with headers, method and abort signal
Downloads.enqueue Download to a file with ranges, resume and completion receipts
<Image> Local baked assets and remote PNG/JPEG decoding
Archives.extract ZIP, TAR and 7z extraction with a destination directory
Archives.create Create ZIP or TAR archives from files and directories
Sound Play baked WAV clips with volume and pan
Notifications / Users / DeviceInfo Notifications, users and device information
FileSystem Read, write, list, rename and inspect files
Controller / useGamepad Light bar, vibration and per-player pad state (playerIndex 0..3)
Packages.install Install a PKG through BGFT; requires a privileged app
Packages.uninstall Remove a title through sceAppInstUtil; requires a privileged app
Payloads Check GoldHEN BinLoader and send an ELF payload to 127.0.0.1:9090
Sse Server-Sent Events stream with event polling and cancellation
WebSocket ws/wss text client with polling, ping/pong and close
Music Local and HTTP(S) MP3/OGG playback, seek (local), metadata, playlists and crossfade
Video Local MP4/H.264 playback through sceAvPlayer; pause/resume/seek/stop
SaveData Mount, unmount and delete PS4 save data; repairBroken recovers a broken directory
Keyboard.prompt Open the system on-screen keyboard
Dialog System message dialogs (alert, confirm and progress)
AppState App lifecycle state and system events (resume, URL open, focus)
Fonts / BackHandler / Power / Linking Text language, exit, keep-awake and URLs

BrowserCapture is not part of the PS4 runtime. Opus, album art and system BGM are pending. Video currently targets 480p on the software path; the Vulkan build can present the UI and video frames through Y/UV textures, while 720p/1080p decoding and HDR remain pending.

Save data and the system keyboard are available from the same import:

import {SaveData, Keyboard, FileSystem} from '@ps4-react/core';

const save = SaveData.mount({dirName: 'settings', title: 'My App', repairBroken: true});
FileSystem.writeFile(`${save.path}/settings.json`, '{"name":"Player"}', {sync: true});

const result = await Keyboard.prompt({title: 'Player name', value: 'Player'}).done;
console.log(result.text);

The settings sample in samples/ demonstrates both APIs.

Paths:

  • /app0 — read-only package contents (the PKG root);
  • /download0 — writable application data, mapped to /data/PS4React;
  • /cache0 — image and cache data.

Project layout

app/                 React starter application (JSX, assets, sounds)
samples/             Example apps built with -Sample <name>
assets/              PKG icons and CA bundle
native/ps4/          PS4 host: VideoOut, input, audio, network, images,
                     archives, text shaping and packaging glue
runtime/js/          React runtime and focus/navigation components
tools/               build, bundling, packaging and load-image validation
patches/             pinned Embedded React patches
.github/workflows/   GitHub Actions build

Status

Validated on PS4 hardware:

  • VideoOut 1920×1080 at ~60 fps;
  • React/QuickJS starter with focus and input;
  • big-app PKG registration (CATEGORY=gd) and a dlmalloc heap over mapped system flexible memory, replacing the stock libc heap that fails on retail;
  • clean Options exit through sceKernelGetAppInfo and sceSystemServiceKillApp, with save-data unmount before the system suspends the title;
  • sceAudioOut mixer and interface sounds;
  • HTTPS requests (IPv4, CA bundle in /app0);
  • downloads to /download0 with completion receipts and resume;
  • remote PNG decode at 256×256;
  • ZIP extraction with two entries;
  • Japanese, Simplified Chinese and Arabic shaping at 59.9 fps;
  • PS4 save-data mount and broken-directory recovery, with JSON persistence through the settings sample;
  • the system on-screen keyboard feeding text back into React;
  • system message dialogs (Dialog.alert/Dialog.confirm) with Cross confirm and input suppression while a dialog or the keyboard is open;
  • background/active lifecycle with save-data unmount/remount across the PS button and resume;
  • app relaunch through BackHandler.exitApp({relaunch: true}) with sceSystemServiceLoadExec.

Known limitations:

  • RAR/RAR5 extraction is not available yet; ZIP/TAR/7z are supported.
  • Opus, album art and system BGM are not implemented yet.
  • Video playback uses the software decoder and CPU NV12 conversion on the default build (480p30). The Vulkan build uploads Y/UV textures instead; AAC audio is validated, while 720p/1080p and hardware decoding are pending. Video apps close through sceSystemServiceLoadExec("exit", nullptr) because KillApp's suspend waits for a decoder GPU submit that never completes.
  • Packages requires an app packaged with "privileged": true; it loads the internal AppInstUtil/BGFT sysmodules and installs through BGFT. Validated on the target PS4 5.05/GoldHEN console; large and invalid PKGs are untested.
  • Payloads.isAvailable reads GoldHEN's config: a bare TCP connect to port 9090 can stop BinLoader's accept loop. Use Payloads.send as the real test.
  • Runtime text shaping needs the app to package the Noto fonts it uses.
  • Hot reload only replaces JavaScript; asset changes require a new PKG.

Licenses

The project is GPL-3.0-or-later with the attribution term in LICENSE-ATTRIBUTION. Third-party notices are in NOTICE and licenses/.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages