mcpField
B
bevy-wasm-webgpu

bevy-wasm-webgpu

github.com/chrisgliddonDevelopment2682 installsUpdated 9w ago
Repository

About bevy-wasm-webgpu

A Bevy 0.19 skill for building browser-based WebAssembly clients. It guides developers through WebGL2 or WebGPU selection, bindings, asset serving, artifact size, and common browser deployment issues.

Key features

  1. 01Configure Bevy for wasm32-unknown-unknown
  2. 02Choose WebGL2 or WebGPU output
  3. 03Generate web-target JavaScript bindings
  4. 04Serve assets from the expected path
  5. 05Troubleshoot canvas and browser constraints

Use cases

  1. 01Build a browser version of a Bevy game
  2. 02Select a renderer for target browsers
  3. 03Resolve missing canvas or asset errors
  4. 04Reduce and verify WASM build artifacts

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/chrisgliddon/bevy-skills --skill bevy-wasm-webgpu

After installing, type/bevy-wasm-webgpuin Claude Code to confirm it loaded.

Details

From the project README

Bevy 0.19 — browser WASM

When to use this skill

  • Build a Bevy client for wasm32-unknown-unknown.
  • Choose the broadly compatible WebGL2 path or WebGPU path.
  • Generate JS bindings, serve assets, and reduce artifact size.
  • Diagnose missing canvas, insecure-context, codec, or asset-path failures.

Canonical manifest

[package]
name = "myclient"
version = "0.1.0"
edition = "2024"

[dependencies]
bevy = { version = "0.19", default-features = false, features = [
    "3d",
    "ui",
    "touch",
] }

[profile.wasm-release]
inherits = "release"
opt-level = "z"
lto = "fat"
codegen-units = 1
strip = "debuginfo"

The 3d profile supplies Bevy's renderer, Winit, and the default WebGL2 path. Add audio only if needed; browser audio must begin after user interaction.

Build and serve

rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli

cargo build --profile wasm-release --target wasm32-unknown-unknown
wasm-bindgen --target web --out-name myclient --out-dir public \
  target/wasm32-unknown-unknown/wasm-release/myclient.wasm

# Optional: install Binaryen first, then verify this actually reduces size.
wasm-opt -Oz public/myclient_bg.wasm -o public/myclient_bg.opt.wasm
mv public/myclient_bg.opt.wasm public/myclient_bg.wasm

python3 -m http.server --directory public 8080

Copy or link the project assets/ directory to public/assets/; Bevy fetches assets over HTTP relative to the served page/asset root.

Minimal HTML

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>My Bevy game</title>
    <style>html,body,#bevy{width:100%;height:100%;margin:0;background:#000}</style>
  </head>
  <body>
    <canvas id="bevy"></canvas>
    <script type="module">
      import init from "./myclient.js";
      await init();
    </script>
  </body>
</html>

Bind the primary window to that existing canvas. Otherwise Window::default() has canvas: None, so Bevy/Winit creates and appends a second canvas:

use bevy::{prelude::*, window::WindowPlugin};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                canvas: Some("#bevy".into()),
                fit_canvas_to_parent: true,
                ..default()
            }),
            ..default()
        }))
        .run();
}

Serve over HTTP; opening the file directly does not provide the fetch and module semantics the generated glue expects.

WebGL2 versus WebGPU

ChoiceCargo featuresChoose when
WebGL2profile defaults / webgl2Browser reach matters; no compute dependency
WebGPUadd webgpuA tested target browser supports it and effects need compute

In Bevy 0.19, webgpu overrides webgl2. One binary cannot dynamically fall back between them. Produce two artifacts or choose one based on the supported browser matrix. Check current browser support during release testing rather than hard-coding browser-version claims in application logic.

Gotchas

  • 3d_api only supplies types; it does not render. Use 3d or compose 3d_bevy_render with the app/platform collections.
  • default-features = false matters. Cargo features are additive; adding 3d without disabling defaults keeps the full default set.
  • WebGL2 has no compute shaders. Hanabi and other compute-heavy plugins require the WebGPU artifact and their own current Bevy-compatible release.
  • Browser filesystems and child processes are not native capabilities. Capture, save, and export flows need explicit web APIs/JS interop.
  • Audio playback is normally blocked until a user gesture resumes the browser audio context.
  • Asset 404s are deployment-layout errors: inspect the requested URL in browser devtools and make the served assets/ tree match it.
  • A configured Window.canvas selector must resolve before startup and cannot be changed later. If you omit it, remove any placeholder canvas and let Bevy append its own.
  • Test on actual target browsers and GPUs. cargo check cannot validate adapter limits, shader translation, texture formats, or browser security policy.

See also

Comments

Markdown supported