concept · WebAssembly
Prototype Bridge
Compare the old approach — hand-writing a JS wrapper class around raw Wasm exports — with the new custom-descriptor approach where the Wasm module configures its own JS prototype. Both live demos run the same Counter logic; the code you write is different.
Before: JS wrapper class
wasm exports (imagined)
// Wasm exports raw functions
// instance.exports:
// counter_new(initial) → ptr
// counter_get(ptr) → i32
// counter_inc(ptr)
// counter_add(ptr, n)
javascript — manual wrapper
class Counter {
#ptr;
constructor(initial = 0) {
this.#ptr = exports.counter_new(initial);
}
get() { return exports.counter_get(this.#ptr); }
inc() { exports.counter_inc(this.#ptr); return this; }
add(n) { exports.counter_add(this.#ptr, n); return this; }
}
// Boilerplate duplicated for every Wasm type
Click a button to interact…
Instance→
Counter.prototype→
Object.prototype→
null
After: Custom Descriptors
wat — custom descriptor type
;; Wasm module declares paired types:
(rec
(type $counter
(descriptor $counter.desc)
(struct (field $val (mut i32))))
(type $counter.desc
(describes $counter)
(struct (field (ref null extern)))))
;; Chrome links the JS prototype automatically
javascript — no wrapper class needed
const { instance } = await
WebAssembly.instantiateStreaming(
fetch('counter.wasm'),
imports,
{ builtins: ['js-prototypes'] }
);
const { Counter } = instance.exports;
// Prototype already configured by the module
const c = new Counter(10);
c.inc().add(5);
console.log(c.get()); // 16
Click a button to interact…
WasmGC struct→
Wasm-configured proto→
Object.prototype→
null
What changes: In the old approach every Wasm type needs a hand-written JS class. With custom descriptors the Wasm module calls
wasm:js-prototypes/configureAll once at init time; Chrome links the prototype automatically. The descriptor object is allocated once per type, not per instance, so large collections of WasmGC objects consume significantly less memory.
see also
- Type-Safe Objects — how exact types prevent mismatched descriptor use
- ChromeStatus entry
- Proposal Overview
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗