Zero-copy SharedArrayBuffer architecture. Rust engines compiled to Wasm. React UI at 60fps while your engine runs in the background.
Traditional frameworks collapse under real computation. Alloyhead separates UI intent from compute entirely - different threads, different memory spaces, zero marshalling.
UI and engine share the exact same byte addresses via SharedArrayBuffer. No JSON. No postMessage serialization. No copies.
A ParamBuffer for continuous values (sliders, cursor) and a lock-free SPSC RingBuffer for discrete events (undo, tool switch). Dropping a slider is fine. Dropping an undo is not.
Dual-ChannelBring your own engine. Rust, C++, Go - anything that compiles to wasm32-unknown-unknown. The framework communicates through a strict numeric ABI.
If it takes longer than a millisecond, it doesn't belong on the main thread. The engine runs in a Web Worker. The UI thread captures intent and nothing else.
Off-ThreadWasm traps are caught automatically. After 3 consecutive failures the circuit opens, the last good frame stays visible, and the engine auto-recovers after cooldown.
ResilienceDefine your params and commands once. The compiler generates TypeScript offsets, Rust structs, CRC-32 schema hashes, and cache-line-aligned memory layout.
DXThe UI never waits for compute. The engine never touches the DOM. Memory flows one direction through shared byte addresses.
The new Alloyhead.create() API handles Wasm loading, memory init, the render loop, command demuxing, and output pointer arithmetic. You write application code, not framework plumbing.
Today - manual boilerplate
// 1. Hand-type the Wasm interface interface WasmExports { engine_init: (w: number, h: number) => void; set_params: (g: number, d: number, /* ... */) => void; tick: (dt: number) => number; memory: WebAssembly.Memory; // ...4 more } // 2. Manually instantiate Wasm const buf = await fetch('/engine.wasm') .then(r => r.arrayBuffer()); const wasm = (await WebAssembly.instantiate( buf, { env: { memory: new WebAssembly.Memory({ initial: 32 }) } } )).instance.exports; // 3. Dummy canvas, no-op bridge const bridge = new HostBridge(schema, {}, {}); const dummy = document.createElement('canvas'); await bridge.init(dummy, () => 0); // 4. Manual render loop const loop = () => { wasm.set_params(gravity, damping, ...); bridge.drainCommandsForWasm((cmd, pl) => { switch(cmd) { case CMD.SPAWN_BURST: { const x = pl.getFloat32(2,true); wasm.push_command(1,x,0,0,0); } // ...5 more cases } }); const ptr = wasm.get_particle_buffer_ptr(); const data = new Float32Array( wasm.memory.buffer, ptr, count * 6 ); requestAnimationFrame(loop); };
New API - one await, one object
import { Alloyhead } from '@alloyhead/core'; const sim = await Alloyhead.create({ canvas, schema: physicsSchema, engine: { wasm: '/engine.wasm' }, renderer: 'particles', }); sim.setParams({ gravity, damping, restitution, }); sim.onFrame(({ fps, outputCount }) => { setFps(fps); setCount(outputCount); }); sim.start(); // Commands - no byte offsets, no DataView sim.send('SPAWN_BURST', { count: 100, x: mouseX, y: mouseY }); sim.send('TOGGLE_PAUSE'); // Full control when you need it import { HostBridge } from '@alloyhead/core/advanced'; const bridge = sim.getRawBridge();
send() serializes the object automatically. You never write DataView.setFloat32 again.The web was built to share documents. Alloyhead is an escape hatch for everyone who refuses to accept that browser apps must be slower than native.
SharedArrayBuffer.Reference applications demonstrating different capabilities of the framework. All source ships with early access.
4,000 particles. Gravity, damping, restitution, attractors. Rust engine compiled to Wasm, output read directly from wasm.memory.
Same physics simulation with a TypeScript engine. Useful as a baseline benchmark against the Rust/Wasm version.
Layer-based image editor with brush, fill, transform tools. Demonstrates the RGBA8 buffer pattern and descriptor table compositing.
The framework ships with reference applications and a schema-driven workflow. Here's what the developer experience looks like.
import type { Schema } from '@alloyhead/core'; export const mySchema: Schema = { version: 2, schema_id: 'my-app', parameters: { gravity: { type: 'Float32', default: 9.81 }, damping: { type: 'Float32', default: 0.99 }, cursorX: { type: 'Float32', default: 0 }, cursorY: { type: 'Float32', default: 0 }, }, commands: [ { id: 1, name: 'SPAWN_BURST', payload: { count: 'Uint16', x: 'Float32', y: 'Float32' } }, { id: 2, name: 'CLEAR_ALL' }, ], // Cache-line optimization access_groups: [ ['cursorX', 'cursorY'], ], };
Alloyhead is currently in developer preview. We're onboarding a small group of engineers before the public open-source launch. Drop us an email and we'll send you access to the repo, docs, and Discord.
Open source under MIT · coming soon
Alloyhead is going open source under MIT. Built for engineers who refuse to accept that web apps must be slower than native. Get early access today.