# Support for Reference Types

WebAssembly recently has gained support for a new value type called `externref`.
Proposed in the [WebAssembly reference types
repo](https://github.com/webassembly/reference-types) this feature of
WebAssembly is hoped to enable more efficient communication between the host
(JS) and the Wasm module. This feature removes the need for much of the JS glue
generated by `wasm-bindgen` because it can natively call APIs with JS values.

For example, this Rust function:

```rust
#[wasm_bindgen]
pub fn takes_js_value(a: &JsValue) {
    // ...
}
```

generates this JS glue *without* reference types support:

```js
const heap = new Array(32).fill(undefined);

heap.push(undefined, null, true, false);

let stack_pointer = 32;

function addBorrowedObject(obj) {
    if (stack_pointer == 1) throw new Error('out of js stack');
    heap[--stack_pointer] = obj;
    return stack_pointer;
}

export function takes_js_value(a) {
    try {
        wasm.takes_js_value(addBorrowedObject(a));
    } finally {
        heap[stack_pointer++] = undefined;
    }
}
```

We can see here how under the hood the JS is managing a table of JS values which
are passed to the Wasm binary, so Wasm actually only works in indices. If we
compile with `-Ctarget-feature=+reference-types` (by default since Rust v1.82),
however, the generated JS looks like:

```js
export function takes_js_value(a) {
    wasm.takes_js_value(a);
}
```

And that's it! The WebAssembly binary takes the JS value directly and manages it
internally.

Currently this feature is supported in Firefox 79+ and Chrome. Support in other
browsers is likely coming soon! In Node.js this feature is behind the
`--experimental-wasm-anyref` flag, although the support does not currently align
with the upstream specification as of 14.6.0.
