BLIT386BLIT386

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).

BrowserVersionStatus
Chrome/Edge113+Enabled by default
Firefox141+ (Windows)Enabled by default; 145+/147+ on macOS; Nightly on Linux/Android
Safari26+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.

BrowserMP3OGG (Vorbis)WAVWebM (Opus/Vorbis)
Chrome/EdgeYesYesYesYes
FirefoxYesYesYesYes
SafariYesNoYesNo

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.

BrowserMinimum versionSupport
Chrome/Edge84+Yes
Safari16.4+Yes
Firefox126+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.

CapabilityChrome/EdgeSafariFirefoxNotes
Detection (type + change)YesYesYesAll modern browsers
Lock (screen.orientation.lock())Android YesNo (iOS)LimitedDesktop 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

Last updated on September 9, 2026

On this page