Agent RulesAgent Rules
Builder
Options
Browse all rules by language and framework
Templates
Pre-built rule sets ready to use
Popular Rules
Top community-ranked rules leaderboard
GuidesAnalyzePricingContact
Builder
OptionsTemplatesPopular Rules
GuidesAnalyzePricingContact

Product

  • Builder
  • Templates
  • Browse Rules
  • My Library

Learn

  • What are AI Agent Rules?
  • Guides
  • FAQ
  • About

Resources

  • Terms
  • Privacy Policy
  • Pricing
  • Contact
  • DMCA Policy

Support

Help keep this project free.

Agent RulesAgent Rules Builder
© 2026 Aurora Algorithm Inc.
Back to Templates

Rust + WebAssembly

Rules for building WebAssembly modules with Rust for web applications.

rustRust/webassemblyWebAssembly
rust
wasm
webassembly
wasm-bindgen
web
Customize in Builder

Details

Language
rustRust
Framework
webassemblyWebAssembly

Rules Content

AGENTS.md
Edit in Builder

Rust WebAssembly Agent Rules

Project Context

You are building a Rust library compiled to WebAssembly for use in browsers or Node.js runtimes. The codebase uses wasm-bindgen for JS interop, wasm-pack for building, and the web-sys/js-sys ecosystem for browser API access.

Code Style & Structure

- Run `cargo fmt` and `cargo clippy -- -D warnings` before every commit; use `#![warn(clippy::all, clippy::pedantic)]` in `lib.rs`.
- Set `crate-type = ["cdylib", "rlib"]` in `Cargo.toml` — `cdylib` for the wasm binary, `rlib` for native tests.
- Separate pure Rust logic (no wasm-bindgen dependencies) in `src/core/` from JS-facing wrappers in `src/bindings/`.
- Call `console_error_panic_hook::set_once()` in an exported `init()` function so panics show in the browser console.
- Write `///` doc comments for all `#[wasm_bindgen]` items with usage examples in JavaScript.

wasm-bindgen & JS Interop

- Annotate all JS-facing functions and types with `#[wasm_bindgen]`.
- Keep the wasm boundary thin: accept and return primitives (`u32`, `f64`, `bool`), `String`, `Vec<u8>`, or `JsValue`.
- Use `serde-wasm-bindgen` with `serde::Serialize/Deserialize` for complex types instead of manual `JsValue` construction.
- Use `#[wasm_bindgen(js_name = "camelCaseName")]` to expose idiomatic JavaScript API names.
- Return `Result<T, JsError>` from exported functions so JavaScript callers receive proper `Error` objects.
- Use `#[wasm_bindgen(typescript_custom_section)]` to provide accurate TypeScript type declarations for exported items.
- Avoid passing large data structures across the boundary repeatedly; prefer bulk transfer operations.

Browser APIs (web-sys & js-sys)

- Enable only the web-sys features you use in `Cargo.toml` — the full feature set inflates compile time significantly.
- Wrap browser API calls in helper functions that return `Result<T, JsValue>` to avoid naked `.unwrap()` on optional DOM elements.
- Use `wasm_bindgen_futures::spawn_local` to drive async Rust futures from synchronous JS context.
- Use `js_sys::Promise` and `wasm_bindgen_futures::JsFuture` to `await` JavaScript promises inside Rust async functions.
- Gate `web_sys::console::log_1` calls behind a `#[cfg(debug_assertions)]` check to exclude them from release builds.

Memory Management

- Use `wee_alloc` or `lol_alloc` as the global allocator to minimize the allocator's contribution to binary size.
- Use `js_sys::Uint8Array::view` (unsafe) for zero-copy reading of wasm memory from JavaScript; document lifetime invariants.
- Drop large resources explicitly; `#[wasm_bindgen]` exported structs transferred to JavaScript are GC-managed — ensure you do not hold duplicate Rust references.
- Profile memory with browser DevTools heap snapshots; look for linear growth across user interactions as a signal of leaks.

Error Handling

- Set up `console_error_panic_hook` in the `init()` function before any other wasm code runs.
- Never panic across the wasm boundary — catch panics with a wrapper and convert to `Result` types.
- Define a crate-level `WasmError` enum with `thiserror::Error`; implement `Into<JsValue>` to convert for export.
- Use `?` operator internally; convert to `JsError::new(&e.to_string())` only at exported function boundaries.

Binary Size Optimization

- Set `opt-level = "z"` and `lto = true` in `[profile.release]` for minimum binary size.
- Use `wasm-opt` (run automatically by `wasm-pack build --release`) to shrink the binary further via Binaryen passes.
- Audit binary size with `twiggy top -n 20 pkg/app_bg.wasm` to identify the largest contributors.
- Gate heavy features with Cargo feature flags so callers can opt in to larger bundles only when needed.
- Avoid pulling in `std::fmt` formatting machinery for error strings in size-critical paths; use fixed error codes instead.
- Target under 200 KB gzipped for utility libraries; under 500 KB for full interactive applications.

Testing

- Write pure Rust unit tests in `#[cfg(test)]` modules for all core logic — no browser required.
- Write wasm integration tests with `#[wasm_bindgen_test]` in `tests/` and run with `wasm-pack test --headless --chrome`.
- Test that exported functions return proper JS `Error` objects by calling them from `#[wasm_bindgen_test]` with invalid inputs.
- Set up CI to run both `cargo test` (native) and `wasm-pack test --headless --firefox` on every pull request.
- Benchmark with `criterion` for native tests and browser `performance.measure` APIs for wasm-specific hotpaths.

Related Templates

rust

Rust + Axum

Type-safe Rust web development with Axum, Tokio, and Tower middleware.