Static JS Objects - The `wasm-bindgen` Guide

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# Use of `static` to Access JS Objects

JavaScript modules will often export arbitrary static objects for use with their provided interfaces. These objects can be accessed from Rust by declaring a named `static` in the `extern` block with an `#[wasm_bindgen(thread_local_v2)]` attribute. `wasm-bindgen` will bind a `JsThreadLocal` for these objects, which can be cloned into a `JsValue`.

These values are cached in a thread-local and are meant to bind static values or objects only. For getters which can change their return value or throw see how to import getters.

For example, given the following JavaScript:

    let COLORS = {
        red: 'rgb(255, 0, 0)',
        green: 'rgb(0, 255, 0)',
        blue: 'rgb(0, 0, 255)',
    };

`static` can aid in the access of this object from Rust:

    #![allow(unused)]
    fn main() {
    #[wasm_bindgen]
    extern "C" {
        #[wasm_bindgen(thread_local_v2)]
        static COLORS: JsValue;
    }

    fn get_colors() -> JsValue {
        COLORS.with(JsValue::clone)
    }
    }

Since `COLORS` is effectively a JavaScript namespace, we can use the same mechanism to refer directly to namespaces exported from JavaScript modules, and even to exported classes:

    let namespace = {
        // Members of namespace...
    };

    class SomeType {
        // Definition of SomeType...
    };

    export { SomeType, namespace };

The binding for this module:

    #![allow(unused)]
    fn main() {
    #[wasm_bindgen(module = "/js/some-rollup.js")]
    extern "C" {
        // Likewise with the namespace--this refers to the object directly.
        #[wasm_bindgen(thread_local_v2, js_name = namespace)]
        static NAMESPACE: JsValue;

        // Refer to SomeType's class
        #[wasm_bindgen(thread_local_v2, js_name = SomeType)]
        static SOME_TYPE: JsValue;

        // Other bindings for SomeType
        type SomeType;
        #[wasm_bindgen(constructor)]
        fn new() -> SomeType;
    }
    }

## Optional statics

If you expect the JavaScript value you're trying to access to not always be available you can use `Option<T>` to handle this:

    #![allow(unused)]
    fn main() {
    extern "C" {
        type Crypto;
        #[wasm_bindgen(thread_local_v2, js_name = crypto)]
        static CRYPTO: Option<Crypto>;
    }
    }

If `crypto` is not declared or nullish (`null` or `undefined`) in JavaScript, it will simply return `None` in Rust. This will also account for namespaces: it will return `Some(T)` only if all parts are declared and not nullish.

## Static strings

Strings can be imported to avoid going through `TextDecoder/Encoder` when requiring just a `JsString`. This can be useful when dealing with environments where `TextDecoder/Encoder` is not available, like in audio worklets.

    #![allow(unused)]
    fn main() {
    #[wasm_bindgen]
    extern "C" {
        #[wasm_bindgen(thread_local_v2, static_string)]
        static STRING: JsString = "a string literal";
    }
    }