Architecture
At a high level, three-native embeds a JavaScript runtime and a minimal
browser API shim on top of a native rendering backend.
┌─────────────────────────────────┐
│ Your Game (Three.js) │
├─────────────────────────────────┤
│ Three.js (submodule) │
├─────────────────────────────────┤
│ Browser Shim │ WebGL, DOM, timing, input
├─────────────────────────────────┤
│ mquickjs │ JS runtime
├─────────────────────────────────┤
│ Native Backend (Zig) │ sokol or wgpu-native
└─────────────────────────────────┘
Core Components
- Host runtime (Zig): Owns the process lifecycle and platform integration.
- JS runtime:
mquickjswith a single global context. - Browser shim: Implements the small subset of browser APIs that Three.js expects, especially WebGL.
- Render backend: Translates WebGL-like calls into native GPU API calls.
- Platform layer: Window creation, input capture, timing, and event pumps.
Boot Sequence
- Initialize platform layer and create the primary window.
- Initialize the rendering backend and device state.
- Initialize the JS runtime and register host bindings.
- Load the Three.js bundle and user entry module.
- Create a canvas and WebGL context for the app.
- Enter the frame loop and start
requestAnimationFrame.
Frame Loop
Each frame follows a fixed, explicit order:
- Poll platform events (input, resize, focus).
- Dispatch events into the shim.
- Run one
requestAnimationFrametick in JS. - Translate WebGL calls into native backend commands.
- Present the frame.
The loop is single-threaded in the initial phase to keep behavior deterministic.