bevy-wasm-webgpu
Skill29 starsChanged 11 days agoMITView on GitHub
Use when targeting Bevy 0.20 at `wasm32-unknown-unknown`, choosing the `webgl2` or `webgpu` feature, setting `WgpuSettings { backends, priority: WgpuSettingsPriority::WebGPU }`, attaching to a canvas with `Window { canvas, fit_canvas_to_parent }`, generating glue with `wasm-bindgen`, or debugging asset HTTP 404s and `Task` cancellation in the browser.
In this repository34 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- bevy-a11ySkill
- bevy-animationSkill
- bevy-assetsSkill
- bevy-audioSkill
- bevy-camerasSkill
- bevy-captureSkill
- bevy-cargo-featuresSkill
- bevy-core-conceptsSkill
- bevy-custom-assetsSkill
- bevy-diagnostics-profilingSkill
- bevy-ecs-componentsSkill
- bevy-ecs-queriesSkill
- bevy-ecs-systemsSkill
- bevy-fluentSkill
- bevy-input-actionsSkill
- bevy-migration-0-17-to-0-18Skill
- bevy-migration-0-18-to-0-19Skill
- bevy-migration-0-19-to-0-20Skill
- bevy-pbr-materialsSkill
- bevy-physicsSkill
- bevy-portingSkill
- bevy-renderingSkill
- bevy-save-loadSkill
- bevySkill
- bevy-testingSkill
- bevy-uiSkill
- bevy-vfxSkill
- bevy-voxel-dataSkill
- bevy-voxel-pipelineSkill
- bevy-voxel-runtimeSkill
- similarity-rsSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 0 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 124
Mesh shaders are not supported on web: Keep the mesh_shader_* paths native-only.
- Very specific: line 144
No
std::time::Instantin WASM: Use bevy::platform::time::Instant (bevy::time::Instant no longer exists). - Very specific: line 145
println!is a bare console line: Use info!/warn! for structured devtools output.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Bevy 0.20 — WASM + WebGPU
When to use this skill
- Targeting
wasm32-unknown-unknownfor browser delivery. - Choosing WebGL2 (reach) vs WebGPU (compute, speed).
- Trimming the bundle from 30 MB down to 5–10 MB.
- Pointing Bevy at your own
<canvas>and keeping browser hotkeys alive. - Configuring asset paths so the browser finds
assets/.
Canonical Cargo.toml
[package]
name = "myclient"
version = "0.1.0"
edition = "2024"
[dependencies]
bevy = { version = "0.20", default-features = false, features = [
"3d_bevy_render", # stock 3D renderer + glTF; "3d_api" if you bring your own
"bevy_winit", # window + event loop (not in *_bevy_render)
"default_app", # assets, log, state
"scene", # WorldAssetRoot / glTF spawning
"webgl2", # broadest reach; `default_platform` would add it anyway
"webgpu", # compute shaders, faster; still a Chrome/Edge-first story
"mouse", "keyboard", "touch", "gestures",
# "ui", "audio" — opt-in since 0.19; "ui" requires "picking" for clicks
] }
[profile.release]
opt-level = "z" # size, not speed — WASM is bandwidth-bound
lto = "fat"
codegen-units = 1
strip = "debuginfo"
panic = "abort"Build & serve
cargo build --release --target wasm32-unknown-unknown
wasm-bindgen --target web --out-dir public/ \
target/wasm32-unknown-unknown/release/myclient.wasm
wasm-opt -Oz public/myclient_bg.wasm -o public/myclient_bg.wasm # optional, large win
# `assets/` must sit next to myclient.js: Bevy fetches `./assets/...` relative to the page.
python3 -m http.server -d public/ 8080Canvas and backend selection
use bevy::prelude::*;
use bevy::render::settings::{Backends, WgpuSettings, WgpuSettingsPriority};
use bevy::render::RenderPlugin;
fn main() {
App::new()
.add_plugins(
DefaultPlugins
.set(WindowPlugin {
primary_window: Some(Window {
// CSS selector; Bevy attaches to this element instead of
// appending a new <canvas> to <body>.
canvas: Some("#bevy".into()),
fit_canvas_to_parent: true,
// Keep F5 / Ctrl+R / Tab working in the browser.
prevent_default_event_handling: false,
..default()
}),
..default()
})
.set(RenderPlugin {
render_creation: WgpuSettings {
// None = let wgpu pick (WebGPU if the browser has it, else WebGL2).
backends: Some(Backends::BROWSER_WEBGPU | Backends::GL),
// 0.19+: `WebGPU` (was `Compatibility`). Use `WebGL2` when the
// `webgl2` feature is the only backend you ship.
priority: WgpuSettingsPriority::WebGPU,
..default()
}
.into(),
..default()
}),
)
.run();
}WgpuSettingsPriority::WebGPU requests WebGPU default limits (portable). Functionality asks for everything the adapter has. WebGL2 adds the WebGL2 constraints. Env override: WGPU_SETTINGS_PRIO=webgpu|functionality|webgl2.
Minimal index.html
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>myclient</title></head>
<body style="margin:0;background:#000">
<canvas id="bevy"></canvas>
<script type="module">
import init from "./myclient.js";
init();
</script>
</body>
</html>Gotchas
0.19 → 0.20
- Shaders are WESL.
naga_oil#import/#ifdeffiles fail to load; port to.wesl(import bevy_pbr::render::forward_io::VertexOutput;,@if(FLAG)). Theshader_format_weslfeature is gone (always on) and GLSL support is removed. Plain WGSL still works. - Mesh shaders are not supported on web. Keep the
mesh_shader_*paths native-only. - Texture compression for web:
compressed_image_saver_universal(UASTC/Basis, one file for every GPU). The new defaultcompressed_image_saveremits BCn or ASTC, which browsers only partly expose. Pointer<Press>isPointerPress(flat pointer events) if you handle touch/mouse through picking.
0.18 → 0.19
WgpuSettingsPriority::Compatibility→WgpuSettingsPriority::WebGPU;WGPU_SETTINGS_PRIO=compatibility→webgpu.- Dropping a
Task<T>on web cancels it. Fire-and-forget work needstask.detach(); native behaviour is unchanged. ui,audioare no longer implied by3d/2d. A trimmed web manifest that shipped buttons or sound in 0.18 loses them silently; add the features.bevy_windowleftdefault_app(now incommon_api).3d_api/3d_bevy_renderstill include it.- Android game activity removed from default; irrelevant to wasm but breaks shared cross-platform manifests.
Still true
default-features = truefor WASM = 30 MB+ bundle. Passdefault-features = falseand pick features explicitly.webgl2andwebgpuboth exist in 0.20.1 (bevy/webgl2→bevy_render/webgl→wgpu/webgl;bevy/webgpu→wgpu/webgpu). Build both and let wgpu choose at runtime; with onlywebgl2, setpriority: WgpuSettingsPriority::WebGL2.- Compute shaders need WebGPU. WebGL2 has none; a compute-dependent renderer must require
webgpuand the smaller browser pool. - Assets are served, not bundled.
assets/sits at the page URL root. Embedding needs a custom asset source (embedded_asset!orAssetSourceBuilder). wasm-packvswasm-bindgenCLI. For raw<script type="module">deliverywasm-bindgen --target webis leaner.- COOP/COEP headers (
Cross-Origin-Opener-Policy: same-origin,Cross-Origin-Embedder-Policy: require-corp) are required forSharedArrayBuffer; without themmulti_threadedruns single-threaded in the browser. - No
std::time::Instantin WASM. Usebevy::platform::time::Instant(bevy::time::Instantno longer exists). println!is a bare console line. Useinfo!/warn!for structured devtools output.
Scope
The render/window snippet above is target-agnostic and compile-checked natively. The wasm32 link, wasm-bindgen output and browser behaviour are not exercised by the tester crate.
See also
bevy-cargo-features— the 0.20 feature-implication table behind the manifest above.bevy-assets— asset loading rules,http/https/web_asset_cachesources.bevy-migration-0-19-to-0-20— WESL shader port.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

