KB / decisions / wasm-strategy
Decision: WASM Strategy
Only operations >1ms benefit from WASM; markdown-to-html (79x) justifies it; slower modules kept for future batch APIs.
Decision: WASM Strategy
Date: 2026-05-01
Status: Phase 1–2 complete; remaining work units pending
What was decided
Seven Rust crates were compiled to WASM and replace TypeScript implementations in @duyet/libs. All seven are kept even where WASM is slower than TypeScript.
Benchmark-driven migration rule
Don't migrate a TypeScript function to WASM unless its TypeScript mean exceeds ~1 ms.
For sub-100 µs operations, JS↔WASM string marshaling costs 30–40 µs per call — exceeding the computation time itself. The WASM boundary is only beneficial when compute dominates marshaling.
Only markdown-to-html cleared this bar: 6.3 ms → 0.08 ms (79x speedup). All other modules are at parity or slower.
Why keep slower WASM modules
- Consistency: all modules are already Rust — removing some would split the maintenance surface
- Future batch APIs: processing N items in a single WASM call amortizes the marshal cost; slower single-call modules may become winners under batch workloads
- Cloudflare Workers: WASM boundary cost in a Worker runtime may differ from Bun; benchmarking there is pending
Gitignore consequence
**/pkg/ is gitignored at the root. WASM artifacts must be built from source in CI. The blog's CI job now has the Rust toolchain and wasm-pack steps gated on matrix.app == 'blog'. If other apps start using markdownToHtml at build time, extend the gate.
Architecture
crates/<name>/ # Rust source, crate-type = ["cdylib"]
packages/wasm/pkg/ # compiled WASM + JS bindings (gitignored)
packages/libs/ # re-exports WASM bindings as @duyet/libs
apps/*/ # import from @duyet/libs, not WASM directly
scripts/wasm-build.ts inspects each crate's Cargo.toml and skips non-cdylib targets.
Remaining concerns
unified/remark/rehype,exifreader, anddiff-match-patchare superseded but not yet removed (WU-19)- TanStack Query was added as a dependency (WU-14) but SWR hasn't been removed from agents and ai-percentage yet