Easy to follow guide to building SPAs using Rust, WebAssembly and Yew

WebAssembly (wasm) allows code written in languages other than JavaScript to run on browsers. If you haven’t been paying attention, all the major browsers support wasm and globally more than 90% of users have browsers that can run wasm.

Since Rust compiles to wasm, is it possible to build SPAs (Single Page Applications) purely in Rust and without writing a single line of JavaScript? The short answer is YES! Read on to learn more or visit the demo site if you can’t contain your excitement!

We’ll be building a simple ecommerce site called “RustMart” that will have 2 pages:

  • HomePage - list all the products that the customer can add to cart
  • ProductDetailPage - show the product details when a product card is clicked

I’m using this example as it tests the minimal set of capabilities required to build modern SPAs:

  • Navigate between multiple pages without page reload
  • Make network requests without page reload
  • Ability to reuse UI components across multiple pages
  • Update components in different layers of the UI hierarchy

Setup

Follow this link to install Rust if you haven’t done so already.

Install these Rust tools:

$ cargo install wasm-pack          ## Compile Rust to Wasm and generate JS interop code
$ cargo install cargo-make         ## Task runner
$ cargo install simple-http-server ## Simple server to serve assets

Create a new project:

$ cargo new --lib rustmart && cd rustmart

We’ll be using the Yew library to build UI components. Let’s add this and wasm dependencies to Cargo.toml:

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

[dependencies]
yew = "0.17"
wasm-bindgen = "0.2"

Create a new file named Makefile.toml and add this:

[tasks.build]
command = "wasm-pack"
args = ["build", "--dev", "--target", "web", "--out-name", "wasm", "--out-dir", "./static"]
watch = { ignore_pattern = "static/*" }

[tasks.serve]
command = "simple-http-server"
args = ["-i", "./static/", "-p", "3000", "--nocache", "--try-file", "./static/index.html"]

Start the build task:

$ cargo make build

If you’re new to Rust, I’ve written some guides for beginners which will help you follow this post better.

Hello World

Let’s start with a simple “hello world” example:

Create static/index.html and add this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>RustMart</title>
    <script type="module">
      import init from "/wasm.js";
      init();
    </script>
    <link rel="shortcut icon" href="#" />
  </head>
  <body></body>
</html>

Add this to src/lib.rs:

// src/lib.rs
use wasm_bindgen::prelude::*;
use yew::prelude::*;

struct Hello {}

impl Component for Hello {
    type Message = ();
    type Properties = ();

    fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
        Self {}
    }

    fn update(&mut self, _: Self::Message) -> ShouldRender {
        true
    }

    fn change(&mut self, _: Self::Properties) -> ShouldRender {
        true
    }

    fn view(&self) -> Html {
        html! { <span>{"Hello World!"}</span> }
    }
}

#[wasm_bindgen(start)]
pub fn run_app() {
    App::<Hello>::new().mount_to_body();
}

Lot of things going on but you can see that we’re creating a new component named “Hello” that renders <span>Hello World!</span> into the DOM. We’ll learn more about Yew components later.

Start the serve task in a new terminal and load http://localhost:3000 in your browser

$ cargo make serve

It works!! It’s only “hello world” but this is fully written in Rust.

Let’s learn about components and other SPA concepts before proceeding further.

#rust #webassembly #wasm #web-development #developer

Building Single Page Applications using Rust, WebAssembly and Yew
16.85 GEEK