---
obj: concept
mime: application/wasm
extension: wasm
website: https://webassembly.org
rev: 2024-03-26
---

# WebAssembly
WebAssembly, often abbreviated as Wasm, is an open standard and binary instruction format designed for a stack-based virtual machine. It aims to execute code efficiently across various platforms, including web browsers. WebAssembly is a portable binary instruction format that serves as a compilation target for high-level programming languages like C, C++, and [Rust](programming/languages/Rust.md). It enables these languages to be executed in web browsers at near-native speeds, bridging the performance gap between web applications and native applications.

## Features of WebAssembly
### 1. **Efficiency**
   - WebAssembly binaries are designed to be compact and fast to load, enabling efficient transmission over the network.
   - It leverages Just-In-Time (JIT) compilation techniques for optimal runtime performance.

### 2. **Safety**
   - WebAssembly runs in a sandboxed environment within the browser, providing a high level of security.
   - It uses a memory-safe, sandboxed execution model to prevent malicious code from compromising the host environment.

### 3. **Compatibility**
   - WebAssembly is designed to be platform-independent, allowing code to run consistently across different architectures and operating systems.
   - It integrates seamlessly with existing web technologies like JavaScript, enabling interoperability with web applications.

### 4. **Versatility**
   - WebAssembly can be used for a variety of use cases beyond web development, including server-side applications, game engines, and multimedia processing.

## How WebAssembly Works

WebAssembly code is typically generated by compiling source code written in languages like C, C++, or [Rust](programming/languages/Rust.md) using specific compilers such as Emscripten or the [Rust](programming/languages/Rust.md) compiler with the `wasm32-unknown-unknown` target.

Once compiled, the WebAssembly code can be executed within a web browser using the JavaScript-based WebAssembly runtime. Alternatively, it can be run outside the browser using standalone WebAssembly runtimes or integrated into existing software systems.

## Use Cases of WebAssembly
WebAssembly has various applications across different domains:
- **Web Development**: Enhancing web applications with high-performance computations, multimedia processing, and gaming.
- **Server-Side Applications**: Running compute-intensive tasks efficiently on the server.
- **Game Development**: Building cross-platform games with near-native performance.
- **Multimedia Processing**: Processing and manipulating multimedia content such as images, audio, and video in the browser.
- **Blockchain**: Executing smart contracts and decentralized applications (DApps) on blockchain platforms.


## Usage with [Rust](programming/languages/Rust.md)
### Requirements
You need [Rust](programming/languages/Rust.md) installed and the following for creating the WebAssembly:
```sh
cargo install wasm-pack
```

### Creating the project
Create a new library:
```sh
cargo new --lib hello-wasm
```

Sample `src/lib.rs`:
```rust
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern {
    pub fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}
```

wasm-pack uses wasm-bindgen, another tool, to provide a bridge between the types of JavaScript and [Rust](programming/languages/Rust.md). It allows JavaScript to call a [Rust](programming/languages/Rust.md) API with a string, or a [Rust](programming/languages/Rust.md) function to catch a JavaScript exception.

### Calling external functions in JavaScript from [Rust](programming/languages/Rust.md)
```rust
#[wasm_bindgen]
extern {
    pub fn alert(s: &str);
}
```

As you might suspect, this is the alert function provided by JavaScript.

Whenever you want to call JavaScript functions, you can add them to this file, and wasm-bindgen takes care of setting everything up for you. Not everything is supported yet, but we're working on it. 

### Producing [Rust](programming/languages/Rust.md) functions that JavaScript can call
```rust
#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}
```

Once again, we see the `#[wasm_bindgen]` attribute. In this case, it's not modifying an `extern` block, but a `fn`; this means that we want this [Rust](programming/languages/Rust.md) function to be able to be called by JavaScript. It's the opposite of `extern`: these aren't the functions we need, but rather the functions we're giving out to the world.

This function is named `greet`, and takes one argument, a string (written `&str`), `name`. It then calls the `alert` function we asked for in the `extern` block above.

### Compiling our code to WebAssembly
To compile our code correctly, we first need to configure it with `Cargo.toml`. Open this file, and change its contents to look like this:
```toml
[package]
name = "hello-wasm"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
description = "A sample project with wasm-pack"
license = "MIT/Apache-2.0"
repository = "https://github.com/yourgithubusername/hello-wasm"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"
```

The big part to add is the `[package]`. The `[lib]` part tells [Rust](programming/languages/Rust.md) to build a `cdylib` version of our package.
The last section is the `[dependencies]` section. Here's where we tell [Cargo](../applications/development/cargo.md) what version of `wasm-bindgen` we want to depend on.

### Building the package
Now that we've got everything set up, let's build the package. We'll be using the generated code in a native ES module and in Node.js. For this purpose, we'll use the `--target` argument in `wasm-pack build` to specify what kind of WebAssembly and JavaScript is generated.

```sh
wasm-pack build --target web
```

This does a number of things (and they take a lot of time, especially the first time you run `wasm-pack`). In short, `wasm-pack build`:
- Compiles your [Rust](programming/languages/Rust.md) code to WebAssembly.
- Runs `wasm-bindgen` on that WebAssembly, generating a JavaScript file that wraps up that WebAssembly file into a module the browser can understand.
- Creates a `pkg` directory and moves that JavaScript file and your WebAssembly code into it.
- Reads your `Cargo.toml` and produces an equivalent `package.json`.
- Copies your `README.md` (if you have one) into the package.

### Using the package on the web
Now that we've got a compiled Wasm module, let's run it in the browser. Let's start by creating a file named `index.html` in the root of the project, so we end up with the following project structure:
```
├── Cargo.lock
├── Cargo.toml
├── index.html  <-- new index.html file
├── pkg
│   ├── hello_wasm.d.ts
│   ├── hello_wasm.js
│   ├── hello_wasm_bg.wasm
│   ├── hello_wasm_bg.wasm.d.ts
│   └── package.json
├── src
│   └── lib.rs
└── target
    ├── CACHEDIR.TAG
    ├── release
    └── wasm32-unknown-unknown
```

Put the following content in the `index.html` file:
```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>hello-wasm example</title>
  </head>
  <body>
    <script type="module">
      import init, { greet } from "./pkg/hello_wasm.js";
      init().then(() => {
        greet("WebAssembly");
      });
    </script>
  </body>
</html>
```

The script in this file will import the JavaScript glue code, initialize the Wasm module, and call the `greet` function we wrote in [Rust](programming/languages/Rust.md).

Serve the root directory of the project with a local web server, (e.g. `python3 -m http.server`).

> Note: Make sure to use an up-to-date web server that supports the `application/wasm` [MIME](../files/MIME.md) type. Older web servers might not support it yet.

Load `index.html` from the web server. An alert box appears on the screen, with `Hello, WebAssembly!` in it. We've successfully called from JavaScript into [Rust](programming/languages/Rust.md), and from [Rust](programming/languages/Rust.md) into JavaScript.