Mystral Native.js
Run JavaScript/TypeScript games natively with WebGPU. Mystral Native.js is a lightweight runtime that lets you write games using familiar Web APIs (WebGPU, Canvas, Audio, fetch) and run them as native desktop applications on macOS, Windows, and Linux.
Think of it as "Electron for games" but without Chromium — just your game code, a JS engine, and native WebGPU rendering.
Note
Mystral Native.js is in early alpha. The core features work — execute JS against WebGPU, Canvas 2D, Web Audio, and fetch — with runtimes available for macOS, Windows, and Linux. Embedding is available for iOS and Android, with a future goal of console support. To see a production build, check out the Sponza demo on itch.io.
Quick Start
Option 1: Install via CLI (Recommended)
macOS / Linux:
curl -fsSL https://mystralengine.github.io/mystralnative/install.sh | bashWindows (PowerShell):
irm https://mystralengine.github.io/mystralnative/install.ps1 | iex
This detects your platform, downloads the latest release, installs to ~/.mystral/ (or $HOME\.mystral\ on Windows), and adds mystral to your PATH. Then run the examples:
# macOS / Linux cd ~/.mystral mystral run examples/triangle.js mystral run examples/mystral-helmet.js # GLTF loading demo
# Windows (PowerShell) cd $HOME\.mystral mystral run examples\triangle.js mystral run examples\mystral-helmet.js # GLTF loading demo
Note
Linux prebuilt binaries work with X11, but not with Wayland. Wayland is supported if you clone and build yourself (see "Build from Source" below). Currently tracking in Issue 18.
Option 2: Download Prebuilt Binary
Download the latest release for your platform from the releases page:
| Platform | Download |
|---|---|
| macOS (Apple Silicon) | mystral-macOS-arm64-v8-dawn.zip |
| macOS (Intel) | mystral-macOS-x64-v8-dawn.zip |
| Windows | mystral-windows-x64-v8-dawn.zip |
| Linux (x64) | mystral-linux-x64-v8-dawn.zip |
| Linux (ARM64) | mystral-linux-arm64-quickjs-wgpu.zip |
unzip mystral-macOS-arm64-v8-dawn.zip
cd mystral-macOS-arm64-v8-dawn
./mystral run examples/triangle.jsOption 3: Build from Source
git clone https://github.com/mystralengine/mystralnative.git cd mystralnative # Install bun if you don't have it curl -fsSL https://bun.sh/install | bash # Download dependencies bun install bun run deps:download # Configure with V8 + Dawn (recommended) cmake -B build \ -DMYSTRAL_USE_V8=ON \ -DMYSTRAL_USE_DAWN=ON \ -DMYSTRAL_USE_QUICKJS=OFF \ -DMYSTRAL_USE_WGPU=OFF # Build cmake --build build --parallel # Run an example ./build/mystral run examples/triangle.js
What Can You Build?
Here's a complete "Hello Triangle" — the traditional first GPU program:
// hello-triangle.js const adapter = await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice(); const context = canvas.getContext("webgpu"); const format = navigator.gpu.getPreferredCanvasFormat(); context.configure({ device, format }); const shader = device.createShaderModule({ code: ` @vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f { var pos = array<vec2f, 3>( vec2f( 0.0, 0.5), vec2f(-0.5, -0.5), vec2f( 0.5, -0.5) ); return vec4f(pos[i], 0.0, 1.0); } @fragment fn fs() -> @location(0) vec4f { return vec4f(1.0, 0.5, 0.2, 1.0); // orange } `, }); const pipeline = device.createRenderPipeline({ layout: "auto", vertex: { module: shader, entryPoint: "vs" }, fragment: { module: shader, entryPoint: "fs", targets: [{ format }] }, }); function render() { const encoder = device.createCommandEncoder(); const pass = encoder.beginRenderPass({ colorAttachments: [{ view: context.getCurrentTexture().createView(), clearValue: { r: 0.1, g: 0.1, b: 0.1, a: 1 }, loadOp: "clear", storeOp: "store", }], }); pass.setPipeline(pipeline); pass.draw(3); pass.end(); device.queue.submit([encoder.finish()]); requestAnimationFrame(render); } render();
Save it and run:
mystral run hello-triangle.js
You'll see an orange triangle on a dark background — rendered natively via WebGPU with no browser involved.
Running Examples
# Basic WebGPU triangle mystral run examples/triangle.js # 3D rotating cube mystral run examples/simple-cube.js # Full 3D scene with PBR lighting (Dawn builds only) mystral run examples/mystral-helmet.js # Day/night cycle demo with atmosphere mystral run examples/daynight.js # Sponza palace with day/night, torches, fireflies (Dawn builds only) mystral run examples/sponza.js # Three.js WebGPU (requires bundling, see docs site for full guide) npm install three@0.182.0 npx esbuild examples/threejs-cube-src.js --bundle --outfile=threejs-bundle.js --format=esm --platform=browser mystral run threejs-bundle.js # PixiJS v8 WebGPU (requires bundling, WebGPU renderer only) npm install pixi.js@^8.0.0 npx esbuild examples/pixijs-sprite-src.js --bundle --outfile=pixijs-bundle.js --format=esm --platform=browser mystral run pixijs-bundle.js # Custom window size mystral run examples/simple-cube.js --width 1920 --height 1080 # Watch mode — auto-reload on file changes mystral run game.js --watch # Headless screenshot (for CI/testing) mystral run examples/simple-cube.js --headless --screenshot output.png
Example Files
| Example | Description |
|---|---|
triangle.js |
Minimal WebGPU — orange triangle |
simple-cube.js |
3D cube with matrices |
test-audio.js |
Web Audio API test |
test-gamepad.js |
Gamepad API test |
mystral-helmet.js |
Full Mystral Engine with DamagedHelmet model |
daynight.js |
Day/night cycle with atmosphere, stars, moon, torches |
sponza.js |
Sponza palace with day/night cycle, torches, fireflies |
threejs-cube-src.js |
Three.js WebGPU example (requires bundling) |
pixijs-sprite-src.js |
PixiJS v8 WebGPU example (requires bundling) |
Bundling for Distribution
Package your game into a single executable that players can run with no dependencies:
# Compile into a standalone binary (Linux/Windows) mystral compile game.js --include assets --out dist/my-game ./dist/my-game # Create a standalone .bundle for macOS .app packaging mystral compile game.js --include assets --bundle-only --out dist/game.bundle
See the distribution guide for platform-specific packaging details including macOS .app bundles, code signing, and more.
Production Builds
Use the production build script to create stripped, optimized, asset-filtered builds locally (mirrors CI):
# Full production build of Sponza demo (strips binary, filters assets, creates .app + .zip) ./scripts/build-production.sh # Build a different demo ./scripts/build-production.sh --demo helmet # Skip cmake rebuild (repackage with existing binary) ./scripts/build-production.sh --skip-build
