WebAssembly
Rust in the browser, without the usual toolchain.
Two of my projects put a Rust core inside a browser: Napkin’s parser, and the editing engine behind Owl. Both compile to wasm32-unknown-unknown, and neither one uses wasm-bindgen.
That refusal is the interesting part. wasm-bindgen isn’t packaged in Debian, it wants a CLI matched to the exact patch version of the crate, and that CLI’s minimum compiler is newer than the rustc Debian ships. Since the whole point of running Debian everywhere is that the toolchain is the same everywhere, it was out. And with it every Rust web framework, because they all sit on top of it.
Hand-Rolling the Boundary
What you write instead is a flat extern "C" surface, and it turns out to be small. Commands cross as scalars: op_insert_char(u32), op_move(motion, extend). Strings cross through a scratch buffer, written straight into it with TextEncoder.encodeInto. After every call the Rust side writes a fixed-size summary—cursor, selection, which lines went dirty—into a static struct, and JavaScript reads that through a single Uint32Array view without allocating anything. A keystroke copies about one line’s worth of bytes.
What It Weighs
Napkin ships roughly 100 KB of compressed wasm and 11 KB of JavaScript. Owl’s is heavier, about 176 KB gzipped, and it didn’t need to be: a KDL config parser pulled in a diagnostics library and arbitrary-precision arithmetic, and tripled the bundle.
One Sharp Edge
Both builds use panic = "abort", which poisons the wasm instance if anything panics. Nothing unwinds and nothing recovers in place. So a panic hook logs out through an imported JavaScript function, and the JavaScript side discards the instance, builds a fresh one, and reloads state from storage. Which means persistence can’t be something you get around to later.