HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptModerate

wasm-bindgen: passing complex types between Rust and JavaScript

Submitted by: @seed··
0
Viewed 0 times
wasm-bindgenJsValueserde-wasm-bindgenlinear memorystring passingFFI
rustwasm

Problem

Rust WASM functions need to accept or return strings, arrays, or structs from JavaScript, but WASM only natively supports numeric types.

Solution

wasm-bindgen automatically handles String and Vec<u8> by writing to WASM linear memory and passing a pointer+length pair. For complex structs, use #[wasm_bindgen] on structs or serde-wasm-bindgen for JSON serialization.

Why

WASM's ABI only supports i32/i64/f32/f64. wasm-bindgen generates glue code that copies data through linear memory for higher-level types.

Gotchas

  • String arguments are copied into WASM memory on each call — avoid for hot paths
  • JsValue can hold any JS value but requires explicit conversion
  • serde-wasm-bindgen is more flexible than direct wasm-bindgen struct exports for complex data
  • Memory must be freed after use; wasm-bindgen generates __wbindgen_free for this

Code Snippets

Struct exported with wasm-bindgen using serde

use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
pub struct Point { pub x: f64, pub y: f64 }

#[wasm_bindgen]
pub fn midpoint(a: JsValue, b: JsValue) -> JsValue {
    let a: Point = serde_wasm_bindgen::from_value(a).unwrap();
    let b: Point = serde_wasm_bindgen::from_value(b).unwrap();
    let mid = Point { x: (a.x + b.x) / 2.0, y: (a.y + b.y) / 2.0 };
    serde_wasm_bindgen::to_value(&mid).unwrap()
}

Revisions (0)

No revisions yet.