---
title: "Decision: Keep the Markdown engine in Rust + WASM"
url: https://mdfy.app/5DWOm2ya
updated: 2026-05-14T18:15:49.480Z
source: "mdfy.app"
---
# 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-opt` is disabled 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.
