dwasm

dwasm

Production-grade build tool for Leptos WASM frontends. Fixes the wasm-opt bulk-memory issue that breaks trunk build --release.

crates.io downloads MIT
cargo install dwasm

The Problem

Modern Rust compilers emit memory.copy and memory.fill instructions in WASM output. Trunk's bundled wasm-opt runs without --enable-bulk-memory, causing hundreds of validation errors on release builds:

[wasm-validator error] memory.copy operations require bulk memory [--enable-bulk-memory-opt]

dwasm solves this by running wasm-opt with the correct flags automatically, plus handles content hashing and index.html patching.

Pipeline

1cargo build --release --target wasm32-unknown-unknown
2wasm-bindgen --target web --no-typescript
3wasm-opt -Oz --enable-bulk-memory
4Content-hash filenames (SHA-256)
5Patch index.html references + strip integrity hashes

Workspace Support

Build a crate inside a Cargo workspace. Auto-finds crates in crates/ subdirectory.

dwasm --crate-name my-web \
  --project /path/to/workspace

Standalone Crates

Build a standalone Leptos crate that isn't part of a workspace.

dwasm --crate-name my-app \
  --project . --standalone

Skip wasm-opt

Fast dev builds without optimization. Still does hashing and HTML patching.

dwasm --crate-name my-app \
  --project . --standalone --skip-opt

Size Reduction

Typical results with recommended Cargo profile: 40-55% WASM size reduction via wasm-opt -Oz.

Recommended Cargo Profile

[profile.release]
opt-level = "s"     # Optimize for size
lto = true          # Link-time optimization
codegen-units = 1   # Better optimization
# NOTE: do NOT add strip=true — it breaks WASM

Requirements

# wasm32 target
rustup target add wasm32-unknown-unknown

# wasm-bindgen CLI (must match your Cargo.lock version)
cargo install wasm-bindgen-cli

# wasm-opt (auto-detected from trunk cache or PATH)
# dwasm finds it at ~/.cache/trunk/wasm-opt-*/bin/wasm-opt