Decision: Keep the Markdown engine in Rust + WASM
Recurring conversation that I'm now closing.
The question that keeps coming up
"Why not just use remark / markdown-it / marked? They run in JS, no WASM boundary, no Rust build step."
The answer
We've measured this three times across the last six months. The Rust + WASM build via comrak is:
- 2.3x faster on cold render (a 200KB doc renders in 4.1ms vs ~9.5ms for
remark) - Reference-correct on GFM.
remark's plugin stack drifts on tables, task lists, and footnotes in ways we hit in user reports. - Stable. The build is
cargo build --target wasm32-unknown-unknown+wasm-bindgen. Three commands. The CI pipeline is 38 seconds end to end.
The friction:
- We can't use
syntect(the C bindings don't compile to WASM cleanly). Highlighting moved client-side to highlight.js. That's a Phase 1 paper cut that became permanent. Fine. wasm-optis in our release profile because the current upstream rejects bulk-memory operations that LLVM emits. We accept the ~8% size hit until the toolchain catches up.
The case I'd entertain re-litigating
If markdown-rs (also Rust → WASM) caught up to comrak on GFM fidelity AND shipped TypeScript types, we'd evaluate. As of 2026-Q2 it's not there. Saved as a watch item.
Receipts
- Bench harness:
packages/engine/benches/render.rs(16 test docs, p95 across 1000 runs) - The last argument I had with myself about this: 2026-02-14, when I was tired and considered punting WASM. The 30-min experiment that morning settled it:
marked.parse(largeDoc)blocked the main thread for 80ms+. The WASM call doesn't.