Skip to content
Back to skills

Wasm Bindgen Js Interop

ASecurity

wasm-bindgen Rust↔JavaScript interop — export Rust functions/structs to JS, import JS APIs into Rust, wasm-pack build pipeline, TypeScript type generation, memory management across the boundary. Sources: rustwasm/wasm-bindgen (MIT/Apache-2.0).

  • 10 stars
  • 0 votes
  • 0 copies
  • 5 views
  • Added September 9, 2026
ai-agentsjavascripttypescriptrustgojavabashnodenodejsapiperformance

Works with

  • api

Security analysis

A100/100

Scanned September 9, 2026

npx -y skills add yanacuti1121/Yana-AI --skill wasm-bindgen-js-interop --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Wasm Bindgen Js Interop?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Wasm Bindgen Js Interop
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/yanacuti1121-wasm-bindgen-js-interop/badge)](https://www.skillsdirectory.com/skills/yanacuti1121-wasm-bindgen-js-interop)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: wasm-bindgen-js-interop
description: wasm-bindgen Rust↔JavaScript interop — export Rust functions/structs to JS, import JS APIs into Rust, wasm-pack build pipeline, TypeScript type generation, memory management across the boundary. Sources: rustwasm/wasm-bindgen (MIT/Apache-2.0).
origin: yana-ai — synthesized from rustwasm/wasm-bindgen (MIT/Apache-2.0)
license: Apache-2.0
version: 1.0.0
compatibility: yana-ai >= 1.3.55
---

# /wasm-bindgen-js-interop

## When to Use

- Porting compute-intensive Rust to the browser (crypto, image processing, parsers)
- Exposing Rust structs with methods as JavaScript classes
- Calling browser APIs (DOM, fetch, console) from within Rust/WASM
- Generating TypeScript types for Rust WASM exports

## Do NOT use for

- Server-side Node.js native addons (use [[napi-rs-native-addons]])
- Sandboxed untrusted code execution (use [[wasmtime-wasi-sandbox]])
- Pure JavaScript performance optimization

---

## Export Rust → JavaScript

```rust
// Cargo.toml
// [dependencies]
// wasm-bindgen = "0.2"
// wasm-pack = build tool

use wasm_bindgen::prelude::*;

// Export a function
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

// Export a struct with methods → becomes a JS class
#[wasm_bindgen]
pub struct Parser {
    data: Vec<u8>,
}

#[wasm_bindgen]
impl Parser {
    #[wasm_bindgen(constructor)]
    pub fn new(input: &[u8]) -> Parser {
        Parser { data: input.to_vec() }
    }

    pub fn parse(&self) -> JsValue {
        // Return complex data as JSON
        let result = serde_json::json!({ "length": self.data.len() });
        serde_wasm_bindgen::to_value(&result).unwrap()
    }

    pub fn free_memory(self) {
        // wasm_bindgen handles drop automatically; explicit free for manual control
        drop(self);
    }
}
```

---

## Import JavaScript → Rust

```rust
use wasm_bindgen::prelude::*;

// Import browser APIs
#[wasm_bindgen]
extern "C" {
    // window.performance.now()
    #[wasm_bindgen(js_namespace = performance)]
    fn now() -> f64;

    // console.log
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);

    // fetch API
    #[wasm_bindgen(js_namespace = window)]
    fn fetch(url: &str) -> js_sys::Promise;
}

#[wasm_bindgen]
pub fn benchmark(n: u32) -> f64 {
    let start = now();
    for _ in 0..n { /* work */ }
    now() - start
}
```

---

## wasm-pack build pipeline

```bash
# Install
cargo install wasm-pack

# Build for bundler (webpack/vite) — generates .wasm + .js + .d.ts
wasm-pack build --target bundler --out-dir pkg

# Build for Node.js
wasm-pack build --target nodejs --out-dir pkg

# Build for plain <script> tag
wasm-pack build --target web --out-dir pkg

# pkg/ contains:
#   my_lib.wasm       — compiled WASM binary
#   my_lib.js         — JS glue code
#   my_lib.d.ts       — TypeScript type definitions (auto-generated!)
#   package.json      — ready to npm publish
```

---

## JavaScript/TypeScript consumption

```typescript
// Bundler target (Webpack / Vite)
import init, { Parser, greet } from './pkg/my_lib.js';

async function main() {
  // Must init (loads .wasm binary) before calling exports
  await init();

  console.log(greet("World"));   // "Hello, World!"

  // Structs become JS classes with automatic memory management
  const parser = new Parser(new Uint8Array([1, 2, 3]));
  const result = parser.parse();
  // IMPORTANT: call free() to release WASM heap memory
  // Otherwise → memory leak (GC doesn't know about WASM heap)
  parser.free();
}
```

---

## Memory management across the boundary

```typescript
// wasm-bindgen structs are NOT GC'd by JavaScript.
// Each #[wasm_bindgen] struct has a .free() method.
// Failing to call it → memory leak in WASM heap.

// Pattern: use try/finally
const parser = new Parser(data);
try {
  return parser.parse();
} finally {
  parser.free();  // always release
}

// For large Uint8Array / Vec<u8> transfers:
// wasm-bindgen copies by default (safe but slow for large buffers)
// Use #[wasm_bindgen] with js_sys::Uint8Array for zero-copy when possible:
```

```rust
#[wasm_bindgen]
pub fn process_buffer(buf: &js_sys::Uint8Array) -> js_sys::Uint8Array {
    let data = buf.to_vec();  // copy into Rust heap
    // ... process ...
    js_sys::Uint8Array::from(data.as_slice())
}
```

---

## Async Rust → JS Promise

```rust
use wasm_bindgen_futures::future_to_promise;

#[wasm_bindgen]
pub fn fetch_and_parse(url: String) -> js_sys::Promise {
    future_to_promise(async move {
        let window = web_sys::window().unwrap();
        let resp = wasm_bindgen_futures::JsFuture::from(window.fetch_with_str(&url)).await?;
        let resp: web_sys::Response = resp.dyn_into()?;
        let json = wasm_bindgen_futures::JsFuture::from(resp.json()?).await?;
        Ok(json)
    })
}
```

---

## Anti-Fake-Pass Checklist

```
❌ Not calling .free() on WASM structs → WASM heap leaks; JS GC cannot collect WASM memory
❌ Not calling init() before using exports → "module not instantiated" runtime error
❌ Passing large Vec<u8> by value → copies entire buffer; use js_sys::Uint8Array reference
❌ Using bundler target for plain HTML → bundler target requires a module bundler; use web target
❌ Importing DOM APIs without web-sys feature flags → must enable specific web-sys features in Cargo.toml
❌ Running wasm-bindgen output in Node.js with bundler target → use nodejs target for Node.js
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.