How to Connect Rust lib + Web Assembly + React.js(typescript)
Published: 2022-10-29 14:27:51

## Summary

In this article, I’ll introduce followings through creating simple demo application.

1. How to create a React app quickly with create-react-app.
2. How to create a Wasm library with Rust.
3. How to create a Wasm library with Rust.

### Create a React App with create-react-app
```
yarn create react-app myApp --template typescript
```
or
```
npx create-react-app myApp --template typescript
```
then you can run this App in your Local Mechine
```
cd myApp
npm start or yarn start
```
Starting the development server...
Compiled successfully!

You can now view react-wasm-tutorial in the browser.

Local: http://localhost:3000
On Your Network: http://192.168.0.153:3000

## Create Rust library for Wasm
To Connected Wasm to the React app, you need to follow these steps.

Create Rust library with cargo.
```
cargo new myApp-lib --lib
```

#### Now Implement a Rust function that you want to call from JavaScript.
Simply, we’ll implement add function and call it from JavaScript.

```
// lib.rs

fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[test]
fn add_test() {
    assert_eq!(1 + 1, add(1, 1));
}
```

#### Wrap the function with wasm-bindgen to export it as Wasm.
wasm-bindgen is Rust library that facilitate high-level interactions between Wasm and JavaScript. For example, you can call Rust(Wasm) from JavaScript, and vice versa.

To add wasm-bindgen dependency, you need to add it to Cargo.toml.

```
[package]
name = "wasm-lib"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

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

[dependencies]
wasm-bindgen = "0.2.78"
```
Then, Let’s wrap the function with wasm-bindgen.

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

#[wasm_bindgen]
fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[test]
fn add_test() {
    assert_eq!(1 + 1, add(1, 1));
}
```
#### Build as Wasm library with wasm-pack
By using wasm-bindgen, you can build Rust as Wasm. However, To load and run Wasm from JavaScript, You need some JavaScript boilerplate codes (like WebAssembly.instantiate).

To do that, you can use wasm-pack!

At first, you need to install it.
```
cd ..
cargo update
wasm-pack --version
=> wasm-pack 0.10.2
```
Then, let’s add npm script to call it by npm run build-lib.
```
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
   "build-lib:wasm": "cd myApp-lib && wasm-pack build --target web --out-dir pkg",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
```


Let’s check the output directory generated by wasm-pack.

You noticed package.json file was generated.

```
$ tree wasm-lib/pkg
├── package.json
├── wasm_lib.d.ts
├── wasm_lib.js
├── wasm_lib_bg.wasm
└── wasm_lib_bg.wasm.d.ts
```
So you can install the Wasm library to other project easily. Let’s install it to the React app.

```
npm install ./wasm-lib/pkg
```
or
```
yarn add ./wasm-lib/pkg
```
#### Call the Wasm function from the React app.
```
import and call
import React, { useEffect, useState } from 'react';
+import init, { add } from "wasm-lib";
import logo from './logo.svg';
import './App.css';

function App() {
+  const [ans, setAns] = useState(0);
+  useEffect(() => {
+    init().then(() => {
+      setAns(add(1, 1));
+    })
+  }, [])
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
+        <p>1 + 1 = {ans}</p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
```
Finaly, you can see this screen.


### Advanced topics
In this article, I provided the quick introduction for Rust and Wasm. To use Wasm in production, you should think about the following topics.

- Logging
- Multi-Threading
- Exception handling
- Call JavaScript from Rust
- Call Rust struct from JavaScript
- Testing
- Cross platform