#[run_example]run-example only.Expand description
This macro helps to run an example in the project’s examples/ directory using a development
server.
The macro expands into:
- A
#[wasm_bindgen(start)]entry-point (compiled only forwasm32) that runs your function body. - A native
main(compiled for all other targets) withdistandstartsubcommands, socargo run --example my_exampleautomatically builds and serves the Wasm bundle without any separatextask/crate.
§Usage
§Minimal example (no arguments)
When no arguments are passed the macro auto-generates a minimal index.html that loads
app.js. This is the recommended approach for most projects.
-
examples/my_example.rs:ⓘuse wasm_bindgen::prelude::*; #[wasm_bindgen] extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); } #[xtask_wasm::run_example] fn run_app() { log("Hello from Wasm!"); } -
Cargo.toml(dev-dependency, wasm32 target only so native builds stay clean):[target.'cfg(target_arch = "wasm32")'.dev-dependencies] xtask-wasm = { version = "*", features = ["run-example"] } -
Run the development server:
cargo run --example my_example
§egui / eframe example
eframe builds on top of wasm_bindgen and uses
web_sys::HtmlCanvasElement directly — no canvas ID string. The pattern below is compatible
with eframe 0.29+.
-
examples/webapp.rs:ⓘuse eframe::wasm_bindgen::JsCast as _; #[xtask_wasm::run_example] fn run() { // Create a <canvas> element dynamically — no index.html canvas needed. let document = web_sys::window().unwrap().document().unwrap(); let body = document.body().unwrap(); let canvas = document .create_element("canvas").unwrap() .dyn_into::<web_sys::HtmlCanvasElement>().unwrap(); canvas.set_id("the_canvas_id"); canvas.set_attribute("style", "width:100%;height:100%").unwrap(); body.append_child(&canvas).unwrap(); let runner = eframe::WebRunner::new(); // `spawn_local` drives the async start() future on the wasm32 executor. wasm_bindgen_futures::spawn_local(async move { runner .start(canvas, eframe::WebOptions::default(), Box::new(|_cc| { Ok(Box::new(MyApp::default())) })) .await .expect("failed to start eframe"); }); } -
Cargo.toml:[target.'cfg(target_arch = "wasm32")'.dev-dependencies] xtask-wasm = { version = "*", features = ["run-example"] } eframe = { version = "0.29", default-features = false, features = ["glow"] } wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = ["HtmlCanvasElement", "Document", "Window", "Element", "HtmlElement"] }
§Arguments
You can give arguments to the macro to customise the example:
app_name- Override the app name used by [xtask_wasm::Dist].index- Provide the full content of a customindex.htmlas a string expression.assets_dir- Path to a custom assets directory.
Warning —
app_name/assets_dirsuppress the auto-generatedindex.html.When either
app_nameorassets_diris set (andindexis not), the macro skips writingindex.htmlinto the dist directory. You must then supply your ownindex.html— either via theindexargument or by placing it in theassets_dir. Forgetting this results in a blank page with no errors, which can be confusing. If you don’t need a custom app name or assets directory, omit all arguments so the macro generates a working HTML page automatically.