NEW The modern web, from 32 MB up

Bare MetalModern Web

PocketJS renders a real Solid app — JSX, Tailwind, signals and TypeScript — natively on the metal. Real flexbox, sub-pixel text and hardware-accelerated animation, at a fluid 60 FPS in 32 MB of RAM.

booting core…
live · tap the on-screen controls to drive it

The stack you already know — running on the metal

Solid JSX Tailwind TypeScript
60 FPS
frame-locked, sustained
32 MB
the whole system's RAM
0 kB
runtime CSS shipped
1 core
PSP, browser & Bun
Engineered down to the byte

A whole UI engine, sized for a handheld

No VDOM. No runtime CSS. No font files shipped. Everything the app can't need is compiled away before it ever reaches the device.

No VDOM

Solid's fine-grained reactivity runs only the effect closures of changed signals. Updates cross a single FFI boundary per frame — never a diff.

Zero runtime CSS

A class string compiles to a style record only if every token is a supported utility. The Tailwind subset resolves at build time — nothing ships to parse.

Baked fonts

Inter is rasterized at build time into coverage atlases for exactly the glyphs you use. No font files, no shaper at runtime — just pixels.

Native animation

Tweens and springs tick in Rust at a fixed 1/60 s. Each frame is a pure function of its index — the reason byte-exact goldens are possible.

Real flexbox

taffy 0.11 — no_std, f32-only — does the layout; text measures natively. The same engine positions every pixel on every host.

One tiny Rust core

Layout, styling, animation, text and the draw list live in one portable no_std core — a few hundred kilobytes, compiled to the PSP and to WebAssembly alike.

Looks like Solid

If you can write a component, you can write for the metal.

You already know the surface: View, Text, signals and class strings. focusable and onPress map straight to the d-pad and face buttons.

  • Dynamic styles are ternaries of full class literals or animate() calls — never runtime CSS.
  • The focus: and active: variants switch natively, with zero JS on focus change.
  • One codebase compiles to a .dcpak for a real PSP and runs unchanged right here in your browser.
Open the playground
Counter.tsx
import { Text, View } from "@pocketjs/core/components";
import { createSignal } from "@pocketjs/core/reactivity";

export default function Counter() {
  const [n, setN] = createSignal(0);
  return (
    <View class="flex-col items-center gap-4 p-6 bg-slate-950">
      <Text class="text-2xl text-slate-50 font-bold">Count: {n()}</Text>
      <View class="px-4 py-2 rounded-xl bg-blue-600 focus:bg-blue-500" focusable onPress={() => setN(n() + 1)}>
        <Text class="text-base text-white font-bold">Press Circle</Text>
      </View>
    </View>
  );
}
Ship it

Every screen deserves the modern web.

It starts on a 2005 handheld with 32 MB of RAM and a fluid 60 FPS. It won't stop there.