Write a frontend application with Rust
Tags: rust, javascript, yew
Published: 2020-04-11 15:41:29

---
title: Write a frontend application with Rust
published: True
description: yew + wasm-pack = HANDY
tags: rust,javascript,yew
---

[yew](https://github.com/yewstack/yew) helps you making a frontend application.
I remind how to do it.

# Prerequests
I need some tools to do it.
Basically it is clear what I need by reading [yew official document](https://yew.rs/docs/).

Now I choose `wasm-pack` to build a wasm application.

```sh
$ cargo install wasm-pack
$ cargo new myapp
$ cd myapp
```

So, I need edit `Cargo.toml` to build using `wasm-pack`.

```toml:Cargo.toml
[dependencies]
yew = { version = "0.14.3", features = ["web_sys"] }
wasm-bindgen = "0.2"

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

Done.

# Write Rust code
I defined my rust application as `lib` type although I created my project as `bin` type.
So I modified my project looks like now.

```sh
myapp
  - src
    - app.rs  # my application body (renamed from `main.rs`)
    - lib.rs  # entrypoint of wasm application (added by manually)
  - Cargo.toml
  - Cargo.lock
```

`app.rs` looks like below.

```rust
use yew::prelude::*;

pub struct Model {
    link: ComponentLink<Self>,
    value: i64,
}

pub enum Msg {
    AddOne,
    SubOne,
}

impl Component for Model {
    type Message = Msg;
    type Properties = ();
    fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
        Self {
            link,
            value: 0,
        }
    }

    fn update(&mut self, msg: Self::Message) -> ShouldRender {
        match msg {
            Msg::AddOne => self.value += 1,
            Msg::SubOne => self.value -= 1,
        }
        true
    }

    fn view(&self) -> Html {
        html! {
            <div>
                <button onclick=self.link.callback(|_| Msg::AddOne)>{ "+1" }</button>
                <button onclick=self.link.callback(|_| Msg::SubOne)>{ "-1" }</button>
                <p>{ self.value }</p>
            </div>
        }
    }
}

```

And `lib.rs` is

```rust
use yew;
use wasm_bindgen::prelude::*;

mod app;

#[wasm_bindgen]
pub fn start() {
    yew::initialize();
    yew::App::<app::Model>::new().mount_to_body();
}
```

`wasm_bindgen` allows to us using our Rust code in javascript world, awesome.

# Build Rust code to wasm application
After wrote Rust code with `yew`, I must run `wasm-pack` for building it.

```sh
$ wasm-pack build
```

So, `wasm-pack` without any parameter generates `pkg` directory.
`pkg` directory has many stuffs that I don't know there are, but I know that there work fine :-).

# Write my frontend code
Now I have wasm code generated by Rust code.
All I need is using it, HOW?
You know anytime MDN documents helps us, refer [this article](https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm).

```sh
$ mkdir site
$ cd site
$ npm init
$ npm i -D webpack webpack-dev-server webpack-cli
$ npm i ../pkg
```

OK, next I write `webpack.config.js`

```javascript
const path = require('path');
module.exports = {
  entry: './index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.js',
  },
  mode: 'development',
  devServer: {
    host: '0.0.0.0',
    port: 55301,
  },
};
```

And `index.html` and `inde.js` which calls the wasm application.

`index.js` is

```javascript
const js = import('./node_modules/myapp/myapp.js');
js.then(js => js.start());
```

`index.html` is

```html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>anond browser</title>
    </head>
    <body>
        <script src="./index.js"></script>
    </body>
</html>
```

# Run server
Now I can ensure my application works fine.

```sh
$ npx webpack-dev-server
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/n0hs05sorazcy3rwsaby.jpg)

Looks good.

# HOT RELOAD?
Yes, of course.
I modify my Rust code while running dev server.

```rust
...
html! {
    <div>
        <h1>{ "Modifying" }</h1>
        ...
    </div>
}
...
```

Build manually.

```sh
$ wasm-pack build
```

After building, dev server detected this changing and reloaded the built wasm application. It means my browser was refreshed and shows new sentence added by me.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9wrthtgh6tjrw6afl239.jpg)

I just said AWESOME EASY, yeah.