Chapter 9: jevhooks-mod, Rust that becomes JavaScript

The mod's routing is written in Rust, and the mod is TypeScript running in a place that has no WebAssembly object. Both of those are true at once, and this crate is how.

Rust can compile to WebAssembly (wasm): a compact, portable machine code that browsers and Node normally run with WebAssembly.instantiate. A mod's realm inside Claude Code has no WebAssembly, so that door is shut. But wasm is simple enough to translate, instruction by instruction, into ordinary JavaScript, and binaryen's wasm2js does exactly that. What comes out is a JavaScript module that behaves like the wasm would have: the same functions, the same flat array of memory, only larger: about 100 KB of optimised wasm becomes about 740 KB of JavaScript.

flowchart LR
  src["src/lib.rs<br/>src/read_only.rs"] -- "cargo build --release<br/>--target wasm32-unknown-unknown" --> wasm["jevhooks_mod.wasm"]
  wasm -- "wasm-opt -Oz<br/>(smaller)" --> opt["jevhooks_mod.opt.wasm"]
  opt -- "wasm2js -O2" --> js["plugin/hooks/jevhooks.js"]
  js -- "imported by" --> bridge["plugin/hooks/bridge.ts"]

That is just mod, line for line. The result is committed, because the plugin loads it as it stands: no build step happens on your machine when Claude Code starts.

Aside: why bother with Rust here at all? Because the routing is the part that must be right in only one direction (chapter 10), and Rust lets it be tested natively with cargo test, in milliseconds, against the same HookEvent the daemon matches on. The TypeScript side is left with plumbing that cannot get a command wrong.

The crate is built two ways at once. crate-type = ["cdylib", "rlib"]: the cdylib is the standalone library that becomes jevhooks_mod.wasm, and the rlib is an ordinary Rust library, which is what cargo test links its native tests against.

Try it. With the devshell (nix develop) and access to the rmcp fork, just mod rebuilds plugin/hooks/jevhooks.js from this crate, and cargo test -p jevhooks-mod runs the routing and filter tests natively.

For the people who maintain it

In this folder

PathWhat
src/Chapter 10: the routing, the read-only filter, and the wasm entry points.
Cargo.tomlcdylib and rlib; depends on jevhooks-events, serde, serde_json.

← Previous: Chapter 8, jevhooks-events/src/ · Up: crates · Next: Chapter 10, jevhooks-mod/src/ →