Browser Support
WebGPU support matrix, automatic software fallback, and build toolchain.
The WebGPU renderer is the default. When WebGPU is unavailable the engine falls back to the Canvas 2D software renderer
automatically; it also runs on browsers that do not expose WebGPU globals at all (for example Firefox on Linux without
Nightly). Use BT.activeBackend to read which backend actually started ('webgpu', 'software', or null before
init).
| Browser | Version | Status |
|---|---|---|
| Chrome/Edge | 113+ | Enabled by default |
| Firefox | 141+ (Windows) | Enabled by default; 145+/147+ on macOS; Nightly on Linux/Android |
| Safari | 26+ | Enabled by default; Safari 18-25 available via Feature Flags |
Point-in-time snapshot
WebGPU rollout is still moving across browsers. Treat this matrix as a snapshot and re-check the vendor release notes periodically.
Build toolchain: Node.js >= 22.18.0 (LTS) and an ESM bundler (Vite, webpack, esbuild, or similar) to load the published
package in the browser. On Vite, the blit386/vite plugin enables hot
reload during development.
Audio formats
AudioClip.load() (see Loading) decodes through the browser's native decodeAudioData(), so
codec support follows the browser, not BLIT386.
| Browser | MP3 | OGG (Vorbis) | WAV | WebM (Opus/Vorbis) |
|---|---|---|---|---|
| Chrome/Edge | Yes | Yes | Yes | Yes |
| Firefox | Yes | Yes | Yes | Yes |
| Safari | Yes | No | Yes | No |
Point-in-time snapshot
Codec support shifts with browser updates. Treat this matrix as a snapshot and re-check the vendor release notes
periodically. This is why AudioClip.load() accepts an ordered fallback list (for example ['theme.ogg', 'theme.mp3'])
- the engine tries each candidate in order until one decodes.
Screen wake lock
Set HardwareSettings.isWakeLockEnabled: true in configure() to keep the screen from dimming or locking during active
gameplay via the Screen Wake Lock API. The engine
acquires the lock after a successful init() and re-acquires it automatically once the page returns to the foreground -
the platform releases the lock on its own while the page is hidden.
| Browser | Minimum version | Support |
|---|---|---|
| Chrome/Edge | 84+ | Yes |
| Safari | 16.4+ | Yes |
| Firefox | 126+ | Yes |
| Android WebView | - | Yes |
Silent no-op fallback
Coverage is broad enough to treat this as a standard feature. On a browser without the Wake Lock API, or when the
platform denies the request (for example a low-battery OS override), the engine logs a console warning and continues -
it never fails init() and there is no fallback behavior to configure.
Screen orientation
Read the current orientation with BT.screenOrientation (a screen.orientation.type string, or null when the API is
unavailable). After init(), the engine listens for orientation changes and calls optional
IBTDemo.onOrientationChange(type). Set HardwareSettings.preferredOrientation to 'landscape' or 'portrait' to
attempt screen.orientation.lock() after init; the default 'any' skips the lock. See
Screen orientation for the API surface and a usage example.
| Capability | Chrome/Edge | Safari | Firefox | Notes |
|---|---|---|---|---|
Detection (type + change) | Yes | Yes | Yes | All modern browsers |
Lock (screen.orientation.lock()) | Android Yes | No (iOS) | Limited | Desktop often requires fullscreen or similar |
Silent no-op fallback
Lock support is uneven - Chrome on Android and Samsung Internet typically allow it; iOS Safari does not. When locking is
unsupported or rejected, the engine continues without unlocking or failing init(). Detection and onOrientationChange
still work wherever screen.orientation exists.
Safari render throttling (macOS Low Power Mode)
macOS Low Power Mode makes Safari/WebKit halve its requestAnimationFrame dispatch rate to about 30 Hz, even on a
120 Hz display and even when the page's JavaScript is nowhere near the frame budget. WebKit first shipped this
throttle for iOS - see WebKit bug 168837, "[iOS] Throttle
requestAnimationFrame to 30fps in low power mode" - and the same WebKit power-saving policy applies on macOS once Apple
added Low Power Mode there in macOS 12 (2021), where it is reproducible on Apple silicon laptops. It is not a web
standard, and a page cannot opt out of it. Chromium (Chrome/Edge) and Gecko (Firefox) do not tie their
requestAnimationFrame cadence to the OS power state this way; both keep dispatching at the display's native rate
regardless of Low Power Mode.
BLIT386's render() runs on requestAnimationFrame, so this halves the render rate while update() keeps advancing at
targetFPS through the fixed-timestep accumulator - see
Multiple update() steps per render frame. Game logic stays
correct; only the visible frame rate drops, and the overlay's frame-metrics row shows the resulting x2 (or higher)
suffix on update(). Turning off Low Power Mode restores a clean 60 fps ceiling on WebKit (capped by its own "prefer
page rendering updates near 60 fps" policy, not the display's full refresh rate).
API history
See also
API: Core
API: Audio
Loading Audio Clips
Hot Reload Guide
Software Fallback Smoke Matrix
Game Loop
Last updated on September 9, 2026