Rust & Wasm: Create Web Apps in Rust using Yew

Nikhil Gupta
2 min readMar 12, 2023

Till now, we have focussed on embedding our Rust-based Wasm modules in the browser or other environments (using Wasmtime). In this article, we will instead create a web application completely in Rust using Yew.

Create a demo yew app

Let’s first create a basic rust project

cargo new yew-demo

and add yew.rs in Cargo.toml with csr feature enabled:

[dependencies]
+yew = { version = "0.20.0", features = ["csr"] }

Next, let’s modify our lib.rs to create an empty html component that will be rendered by our app:

use yew::prelude::*;

#[function_component]
fn App() -> Html {
html! {
}
}

Finally, let’s modify the main to render the app:

fn main() {
yew::Renderer::<App>::new().render();
}

Serve our app using trunk

In order to view our app in the browser, let’s first create an index.html in the root folder:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Yew App</title>
</head>
</html>

Next, let’s install trunk, a WASM web application bundler for Rust.

brew install trunk

Finally, let’s serve our app:

trunk serve

This should build our app and make it accessible at http://127.0.0.1:8080/. Now, we have a web application written in Rust running in our browser! :)

State updates in Yew

Our current app renders an empty page. Let’s try to add some content.

A Hello World simply requires an update in the App component:

fn App() -> Html {
html! {
+ { "Hello World" }
}
}

If you have worked with React, you must be familiar with React hooks like useState that make it easier to add state updates to a web app. Similarly, we can add a state in our Yew App like so:

fn App() -> Html {
+ let counter = use_state(|| 0);
+
html! {
{ "Hello World" }
+ <p>{ *counter }</p>
}
}

However, the counter’s value currently stays at 0. Let’s add a button and a handler to update it:

fn App() -> Html {
let counter = use_state(|| 0);

+ let onclick = {
+ let counter = counter.clone();
+ move |_| {
+ let value = *counter + 1;
+ counter.set(value);
+ }
+ };

html! {
{ "Hello World" }
<p>{ *counter }</p>
+ <button {onclick}>{ "+1" }</button>
}
}

Now, if you run the app, you should be able to increment the counter’s value using the button.

Build for production

Finally, we can use trunk to build our web app for production:

trunk build

This creates a dist folder that can be served by our production server! :)

If you liked this article, subscribe here to get the complete code and updates for the entire collection:

--

--