Install
$ agentstack add skill-chrisgliddon-bevy-skills-bevy-wasm-webgpu ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Bevy 0.18 — WASM + WebGPU
When to use this skill
- Targeting
wasm32-unknown-unknownfor browser delivery. - Choosing the WebGL2 default vs the more capable WebGPU.
- Trimming the bundle from 30 MB down to 5–10 MB.
- Configuring asset paths so the browser actually finds your
assets/folder. - Debugging "context lost" or "no canvas found" errors at startup.
Canonical Cargo.toml
[package]
name = "myclient"
version = "0.1.0"
edition = "2024"
[dependencies]
bevy = { version = "0.18", default-features = false, features = [
# Bring just the renderer + window plumbing.
"3d_api",
"bevy_winit",
# Pick one or both backends. WebGL2 has best browser coverage today;
# WebGPU is faster and supports compute shaders but is still gated on
# current Chrome / Firefox / Safari versions.
"webgl2",
# "webgpu",
# Input — input is NOT in default-features = false anymore in 0.18.
"mouse",
"keyboard",
"touch",
"gestures",
] }
[profile.release]
opt-level = "z" # size, not speed — WASM is bandwidth-bound, not CPU-bound
lto = "fat"
codegen-units = 1
strip = "debuginfo"
panic = "abort"
Build & serve
# 1. Build the WASM binary.
cargo build --release --target wasm32-unknown-unknown
# 2. Bind it for the browser.
wasm-bindgen --target web --out-dir public/ \
target/wasm32-unknown-unknown/release/myclient.wasm
# 3. (Optional but big win) shrink with wasm-opt.
wasm-opt -Oz public/myclient_bg.wasm -o public/myclient_bg.wasm
# 4. Serve. Must serve `assets/` next to `myclient.js` / `myclient_bg.wasm`.
# Bevy looks for `./assets/...` relative to the page URL.
python3 -m http.server -d public/ 8080
Picking a backend
// At runtime, force a backend by setting `WgpuSettings.backends` before
// `DefaultPlugins`. By default Bevy picks the best available.
use bevy::prelude::*;
use bevy::render::settings::{Backends, WgpuSettings};
use bevy::render::RenderPlugin;
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(RenderPlugin {
render_creation: WgpuSettings {
backends: Some(Backends::GL), // WebGL2
// backends: Some(Backends::BROWSER_WEBGPU), // WebGPU
..default()
}
.into(),
..default()
}))
.run();
}
Minimal index.html
myclient
import init from "./myclient.js";
// Bevy auto-finds if present.
init();
Gotchas
default-features = truefor WASM = 30 MB+ bundle. Always passdefault-features = falseand pick features explicitly. This is the single biggest size lever.- Backend coverage 2026: WebGPU is on by default in Chrome and Edge, behind a flag in Firefox and Safari (improving). Ship both if you care about reach — Bevy picks WebGPU when present, falls back to WebGL2 otherwise.
- Compute shaders need WebGPU. WebGL2 has none. If your renderer plugin requires compute, you must build with the
webgpufeature and accept the smaller addressable browser pool. - Assets are served, not bundled.
assets/must sit next to your HTML at the served URL root. There is no built-in embed-in-WASM mode without a custom asset source. wasm-packvswasm-bindgenCLI.wasm-packadds an npm-style wrapper. For raw `delivery,wasm-bindgen --target web` is leaner.- Coop/Coep headers are required for
SharedArrayBuffer, which Bevy's threadpool needs formulti_threaded. Without them you'll be single-threaded in the browser. Configure your server:Cross-Origin-Opener-Policy: same-origin+Cross-Origin-Embedder-Policy: require-corp. - No
std::time::Instantin WASM. Bevy'sTimeworks, but if you use rawstd::time::Instantin a system it panics. Usebevy::time::Instantor wrap behind#[cfg(target_arch = "wasm32")]. println!lands in the JS console as a generic log line. Use thetracingmachinery (info!/warn!) for structured browser-devtools output.
Source-confirmed scope
This skill covers the parts of the WASM workflow that are uncontroversial and stable in 0.18. The Bevy 0.18 release notes did not call out WASM-specific renderer changes; the migration story is mostly the same Cargo-features rename as for native (animation → gltf_animation, etc. — see bevy-cargo-features).
See also
bevy-cargo-features— the feature collection table you need for trimmed WASM builds.bevy-assets— asset loading rules apply identically to WASM, with the file-source caveat above.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: chrisgliddon
- Source: chrisgliddon/bevy-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.