5 ms·
Show HN: Mystral Native – Run JavaScript games natively with WebGPU (no browser)
Hi HN, I've been building Mystral Native — a lightweight native runtime that lets you write games in JavaScript/TypeScript using standard Web APIs (WebGPU, Canvas 2D, Web Audio, fetch) and run them as standalone desktop apps. Think "Electron for games" but without Chromium. Or a JS runtime like Node, Deno, or Bun but optimized for WebGPU (and bundling a window / event system using SDL3).
Why: I originally started by starting a new game engine in WebGPU, and I loved the iteration loop of writing Typescript & instantly seeing the changes in the browser with hot reloading. After getting something working and shipping a demo, I realized that shipping a whole browser doesn't really work if I also want the same codebase to work on mobile. Sure, I could use a webview, but that's not always a good or consistent experience for users - there are nuances with Safari on iOS supporting WebGPU, but not the same features that Chrome does on desktop. What I really wanted was a WebGPU runtime that is consistent & works on any platform. I was inspired by deno's --unsafe-webgpu flag, but I realized that deno probably wouldn't be a good fit long term because it doesn't support iOS or Android & doesn't bundle a window / event system (they have "bring your own window", but that means writing a lot of custom code for events, dealing with windowing, not to mention more specific things like implementing a WebAudio shim, etc.). So that got me down the path of building a native runtime specifically for games & that's Mystral Native.
So now with Mystral Native, I can have the same developer experience (write JS, use shaders in WGSL, call requestAnimationFrame) but get a real native binary I can ship to players on any platform without requiring a webview or a browser. No 200MB Chromium runtime, no CEF overhead, just the game code and a ~25MB runtime.
What it does:
- Full WebGPU via Dawn (Chrome's implementation) or wgpu-native (Rust)
- Native window & events via SDL3
- Canvas 2D support (Skia), Web Audio (SDL3), fetch (file/http/https)
- V8 for JS (same engine as Chrome/Node), also supports QuickJS and JSC
- ES modules, TypeScript via SWC
- Compile to single binary (think "pkg"): `mystral compile game.js --include assets -o my-game`
- macOS .app bundles with code signing, Linux/Windows standalone executables
- Embedding API for iOS and Android (JSC/QuickJS + wgpu-native)
It's early alpha — the core rendering path works well & I've tested on Mac, Linux (Ubuntu 24.04), and Windows 11, and some custom builds for iOS & Android to validate that they can work, but there's plenty to improve. Would love to get some feedback and see where it can go!
MIT licensed.
Repo: https://github.com/mystralengine/mystralnative https://github.com/mystralengine/mystralnative
Docs: https://mystralengine.github.io/mystralnative/ https://mystralengine.github.io/mystralnative/
- danjl 8mo agoLove it. Double bonus points if we could somehow add hardware ray tracing, which is missing from the browser WebGPU implementations. I'll definitely give this a shot with my 3D interactive WebGPU chessboard. A desktop implementation opens up the possibility of publishing on steam and other services which all expect a desktop app.
- Flux159 8mo agoSo in theory it should be possible, but it might require customizing the Dawn or wgpu-native builds if they don't support it (this is providing the JS bindings / wrapper around those two implementations of wgpu.h). But I've already added a special C++ method to handle draco compression natively, adding some mystral native only methods is not out of the question (however, I would want to ensure that usage of those via JS is always feature flagged so that it doesn't break when run on web). Did you write your WebGPU chessboard using the raw JS APIs? Ideally it should work, but I just fixed up some missing APIs to get Three.js working in v0.1.0, so if there are issues, then please open up an issue on github - will try to get it working so we close any gaps.
- danjl 8mo agoHere's a dawn implementation with support for ray tracing that was implemented a number of years ago but never integrated into browsers. Perhaps it will help? https://github.com/maierfelix/dawn-ray-tracing https://github.com/maierfelix/dawn-ray-tracing Yes, chessboard3d.app is written with raw JS APIs and raw WebGPU. It does use the rapier physics library, which uses WASM, which might be an issue? It implements its own ray tracing but would probably run 10x faster with hardware ray tracing support. I think you'd get a lot of attention if you had hardware ray tracing, since that's only currently available in DirectX 12 and Vulkan, requiring implementation in native desktop platforms. FWIW, if the path looks feasible, I would be interested in contributing.
- Flux159 8mo agoWASM shouldn't be an issue since the draco decoder uses it - but it may only work with V8 (for quickjs builds it wouldn't work, but the default builds use V8+dawn). Obviously with an alpha runtime, there may be bugs. I think it would be super cool to have some sort of extension before WebGPU (web) has it. I was taking a look at the prior example & it seems like there's good ongoing discussion linked here about it: https://github.com/gpuweb/gpuweb/issues/535 https://github.com/gpuweb/gpuweb/issues/535. Also I believe that Metal has hardware ray tracing support now too? Re: Implementation, a few options exist - a separate Dawn fork with RT is one path (though Dawn builds are slow, 1-2 hours on CI). Another approach would be exposing custom native bindings directly from MystralNative alongside the WebGPU APIs - that might make iteration much faster for testing feasibility. The JS API would need to be feature-flagged so the same code gracefully falls back when running on web (did this for a native draco impl too that avoids having to load wasm: https://mystralengine.github.io/mystralnative/docs/api/native-apis https://mystralengine.github.io/mystralnative/docs/api/nativ...).