Introduction to WebAssembly(Wasm) with Rust for Beginners
Tags: rust, webassembly, javascript
Published: 2022-09-20 08:00:06

---
title: Introduction to WebAssembly(Wasm) with Rust for Beginners
published: true
date: 2022-08-30 07:31:00 UTC
tags: #rust #wasm #javascript #webassembly
canonical_url: 
---

### Introduction

WebAssembly also known as WASM, is a technology that enables developers to run a set of code on a web browser with native-like performance. It is low-level assembly-like code that runs in the browser alongside JavaScript to achieve performance.

As we all know in terms of performance lower level languages are the fastest like Binary, Assembly language, Higher level languages like C, C++, JavaScript, Python, Java, Ruby, Rust, Swift, and all that most of us use for daily purpose programming. Because these are more human-friendly than machines. There are a set of tools like interpreters, compilers, assemblers and others which convert these languages into machine code to make this understandable to real hardware.

There are programming languages in which we can write our code and ship WebAssembly or Binary(WASM) files. Majorly used ones are Rust, TinyGo(Go), Emscripten(C/C++), and AssemblyScript. All of these languages are known for better performance and memory optimization.

We will use Rust language as a compilation target for our demo of programming.

### Demo

Installation

```
cargo install wasm-pack

```

In this **cargo** is a Rust package manager just like **npm** in node. In Rust, libraries are known as _crates_ like packages in Node. Here above command will install ( **wasm-pack** )[https://github.com/rustwasm/wasm-pack] crate/lib in our system.

##### Initialization

Create a new directory and go to that directory.

```
mkdir wasm-rust-demo && cd wasm-rust-demo

```

##### Create Cargo Package.

```
cargo init

```

Above command will create **Cargo.toml** manifest file(similar like package.json in node) and **src** directory with **main.rs** basic rust file.

##### Edit Cargo.toml

Paste the below code in the _Cargo.toml_ file. It defines crate-type as _cdylib_, which is used when compiling a dynamic library which needs to be loaded from another language like JavaScript in our case. It includes dependency as [**wasm-bindgen**](https://github.com/rustwasm/wasm-bindgen). This crate/package provides communication between Rust and JavaScript with other features.

```
[package]
name = "wasm-rust-demo"
version = "0.1.0"
authors = ["Piyush Goyani <thesourcepedia@gmail.com>"]
edition = "2021"

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

[dependencies]
wasm-bindgen = "0.2"

```

Go to the _src/_ directory, rename **main.rs** to **lib.rs** , and add the following content.

```
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn calc(a: i32, b: i32, op: char) -> i32 {
    if op == '+' {
        return a + b;
    } else if op == '-' {
        return a - b;
    } else if op == '*' {
        return a * b;
    } else if op == '/' {
        return a / b;
    } else {
        return 0;
    }
}

```

Here we are defining a Rust function named **calc** which takes three parameters, two numbers and 3rd for an operator to perform math action and return the result.

### Build

```
 wasm-pack build --target web

```

This command will compile Rust code to wasm and generate a **pkg** directory which can be published to npm as a package and provides files which can be used in JavaScript communication.

![Package Directory Content](https://cdn.hashnode.com/res/hashnode/image/upload/v1661760197249/cQ9TyJShs.png)

##### Error during build

> [INFO]: Installing wasm-bindgen...
> 
> Error: failed to download from https://github.com/WebAssembly/binaryen/releases/download/version\_90/binaryen-version\_90-x86-linux.tar.gz
> 
> To disable `wasm-opt`, add `wasm-opt = false` to your package metadata in your `Cargo.toml`.

Add this line in Cargo.toml

```
[package.metadata.wasm-pack.profile.release]
wasm-opt = false

```

### Running WebAssembly/WASM Code.

#### 1. By Loading Generated JS package

```
<script type="module">
        import init, { calc } from "./pkg/wasm_with_rust.js"
        init().then(() => {
            console.log(calc(10, 2, "+")) // 12
            console.log(calc(10, 2, "-")) // 8
            console.log(calc(10, 2, "*")) // 20
            console.log(calc(10, 2, "/")) // 5
        })
</script>

```

In this, we are loading a javascript file which is generated from **wasm-pack** which does all the job of loading WebAssembly code and all complex memory-related stuff and export functions that we wrote in Rust(e.g _calc()_) and _init()_ to initialize WebAssembly. In this, we are passing two integer parameters and 3rd is an operator which decides which math operation to perform.

#### 2. By Directly Loading **.wasm** File

```
<script>
  WebAssembly.instantiateStreaming(fetch('./pkg/wasm_with_rust_bg.wasm'))
  .then((results) => {
            const calc = results.instance.exports.calc
            console.log(calc(10, 2, 43)) // 12
            console.log(calc(10, 2, 45)) // 8
            console.log(calc(10, 2, 42)) // 20
            console.log(calc(10, 2, 47)) // 5
        })
</script>

```

In this, we are loading the **wasm** binary file directly which is compiled from **wasm-pack**. We are loading using _fetch_ and instantiate using **instantiateStreaming()** method of **WebAssembly** class available globally. Here we are passing the same parameter as above but as you can see 3rd parameter is numeric. That is ASCII value of operator respectively. Here we can not pass string value because are not passing it to JavaScript so it can further convert to Machine Code, but Passing it to directly WASM file.

You can see the WASM Machine code that looks like below. ![WASM Code](https://cdn.hashnode.com/res/hashnode/image/upload/v1661762897772/2YH4xwZ0d.png)

[Source](https://github.com/piyush-multiplexer/wasm-with-rust)

### Resources on WebAssembly

- [WebAssembly](https://webassembly.org/)
- [WebAssembly on MDN](https://developer.mozilla.org/en-US/docs/WebAssembly)

### Advantages

- The Memory of WebAssembly is Linear. It is an expandable continuous buffer of unsigned bytes that can be read and stored from JavaSCript and WASM synchronously.
- Can import JavaScript functions and export custom function logic specified in WASM.
- Compiled to Binary file, Assembly-like language which gives native speed and performance in the browser.
- and many more based on requirements.

### Conclusion

In this tutorial, you get the basic idea of what is WebAssebly or wasm is, its purpose, make wasm binary from Rust Language and how to use it with JavaScript. I hope you enjoyed it give it a thumb, share, and subscribe. Have any doubts or thoughts share them in the comment section below. I am available [here.](https://hashnode.com/@piyushgoyani)