1# Design of `wasm-bindgen` 2 3This section is intended to be a deep-dive into how `wasm-bindgen` internally 4works today, specifically for Rust. If you're reading this far in the future it 5may no longer be up to date, but feel free to open an issue and we can try to 6answer questions and/or update this! 7 8## Foundation: ES Modules 9 10The first thing to know about `wasm-bindgen` is that it's fundamentally built on 11the idea of ES Modules. In other words this tool takes an opinionated stance 12that wasm files *should be viewed as ES modules*. This means that you can 13`import` from a wasm file, use its `export`-ed functionality, etc, from normal 14JS files. 15 16Now unfortunately at the time of this writing the interface of wasm interop 17isn't very rich. Wasm modules can only call functions or export functions that 18deal exclusively with `i32`, `i64`, `f32`, and `f64`. Bummer! 19 20That's where this project comes in. The goal of `wasm-bindgen` is to enhance the 21"ABI" of wasm modules with richer types like classes, JS objects, Rust structs, 22strings, etc. Keep in mind, though, that everything is based on ES Modules! This 23means that the compiler is actually producing a "broken" wasm file of sorts. The 24wasm file emitted by rustc, for example, does not have the interface we would 25like to have. Instead it requires the `wasm-bindgen` tool to postprocess the 26file, generating a `foo.js` and `foo_bg.wasm` file. The `foo.js` file is the 27desired interface expressed in JS (classes, types, strings, etc) and the 28`foo_bg.wasm` module is simply used as an implementation detail (it was 29lightly modified from the original `foo.wasm` file). 30 31As more features are stabilized in WebAssembly over time (like host bindings) 32the JS file is expected to get smaller and smaller. It's unlikely to ever 33disappear, but `wasm-bindgen` is designed to follow the WebAssembly spec and 34proposals closely to optimize JS/Rust as much as possible. 35 36## Foundation #2: Unintrusive in Rust 37 38On the more Rust-y side of things the `wasm-bindgen` crate is designed to 39ideally have as minimal impact on a Rust crate as possible. Ideally a few 40`#[wasm_bindgen]` attributes are annotated in key locations and otherwise you're 41off to the races. The attribute strives to both not invent new syntax and work 42with existing idioms today. 43 44For example a library might exposed a function in normal Rust that looks like: 45 46```rust 47pub fn greet(name: &str) -> String { 48 // ... 49} 50``` 51 52And with `#[wasm_bindgen]` all you need to do in exporting it to JS is: 53 54```rust 55#[wasm_bindgen] 56pub fn greet(name: &str) -> String { 57 // ... 58} 59``` 60 61Additionally the design here with minimal intervention in Rust should allow us 62to easily take advantage of the upcoming [host bindings][host] proposal. Ideally 63you'd simply upgrade `wasm-bindgen`-the-crate as well as your toolchain and 64you're immediately getting raw access to host bindings! (this is still a bit of 65a ways off though...) 66 67[host]: https://github.com/WebAssembly/host-bindings 68