Build Status Join the chat at https://gitter.im/stdweb-rs/stdweb

A standard library for the client-side Web

Documentation

The goal of this crate is to provide Rust bindings to the Web APIs and to allow a high degree of interoperability between Rust and JavaScript.

Examples

You can directly embed JavaScript code into Rust:

```rust let message = "Hello, 世界!"; let result = js! { alert( @{message} ); return 2 + 2 * 2; };

println!( "2 + 2 * 2 = {:?}", result ); ```

Even closures are supported:

```rust let print_hello = |name: String| { println!( "Hello, {}!", name ); };

js! { var printhello = @{printhello}; printhello( "Bob" ); printhello.drop(); // Necessary to clean up the closure on Rust's side. } ```

You can also pass arbitrary structures thanks to [serde]:

```rust

[derive(Serialize)]

struct Person { name: String, age: i32 }

js_serializable!( Person );

js! { var person = @{person}; console.log( person.name + " is " + person.age + " years old." ); }; ```

This crate also exposes a number of Web APIs, for example:

rust let button = document().query_selector( "#hide-button" ).unwrap(); button.add_event_listener( move |_: ClickEvent| { for anchor in document().query_selector_all( "#main a" ) { js!( @{anchor}.style = "display: none;"; ); } });

Design goals

Getting started

Take a look at some of the examples:

Running the examples

  1. Add one of Rust's Web targets with rustup.

  2. Install [cargo-web]:

    $ cargo install -f cargo-web

  3. Go into examples/todomvc and start the example.

  4. Visit http://localhost:8000 with your browser.

For the *-emscripten targets cargo-web is not neccessary, however the native wasm32-unknown-unknown which doesn't need Emscripten requires cargo-web to work!

Exposing Rust functions to JavaScript

WARNING: This is only supported for Rust's native wasm32-unknown-unknown target!

(Note: this is based on the examples/hasher example)

With the stdweb crate you can easily expose a Rust function to JavaScript like this:

```rust

[macro_use]

extern crate stdweb; extern crate sha1;

use sha1::Sha1;

fn hash( string: String ) -> String { let mut hasher = Sha1::new(); hasher.update( string.asbytes() ); hasher.digest().tostring() }

fn main() { stdweb::initialize();

js! {
    Module.exports.sha1 = @{hash};
}

} ```

If you compile this code with cargo-web build --target-webasm you'll get two files:

You can copy them into your JavaScript project and load like any other JavaScript file:

```html

``` After it's loaded you can access `Rust.hasher`, which is a [Promise] which will resolve once the WebAssembly module is loaded. Inside that promise you'll find the contents of `Module.exports` which we've set from our Rust code, which includes our exported function which you can now call: ```html

```

You can also use the very same hasher.js from Nodejs:

```js const hasher = require( "hasher.js" );

const string = "fiddlesticks"; const hash = hasher.sha1( string );

console.log( "Hash of " + string + " is '" + hash + "'" ); ```

For the Nodejs environment the WebAssembly is compiled synchronously.

License

Licensed under either of

at your option.

Snippets of documentation which come from [Mozilla Developer Network] are covered under the [CC-BY-SA, version 2.5] or later.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.