While Rust is known for its backend web development capabilities, the introduction of WebAssembly (Wasm) has enabled the development of rich front-end apps in Rust.
With the introduction of WebAssembly, it became possible to build frontend web apps in Rust, such as the one we just built, expanding development opportunities for developers.
While all of the libraries, frameworks and technologies discussed in this post are still in their early stages of development, the features and capabilities available are already maturing and stable, allowing for larger projects in the future.
What Is WebAssembly and Why Is It Important?
WebAssembly is a compilation target that enables binary code to be executed on web browsers.
It offers high performance and near-native speed for applications that run on the web.
This means that developers can write code in their favorite low-level languages such as C, C++, and Rust which are compiled into WebAssembly and can interact with browser APIs.
It is important to note that we still need some JavaScript to connect WASM to browser APIs for execution hence proving that it is not a replacement for JavaScript but rather a powerful companion.
As we know, JavaScript has never been the ideal language for creating CPU-intensive applications owing to its single-threaded design.
By CPU intensive we mean heavy computation that will need significantly greater CPU clock speed for example machine learning algorithms, video games, and video editing.
JavaScript was initially designed to make web pages interactive by modifying lightweight hypertext files; which is achieved by manipulating the DOM(Document Object Model).
As years went by, a runtime for JavaScript (Node.js) was created that allowed for JavaScript to be written on the server side which came with advantages such as spawning child processes which may alleviate the problem that comes with CPU-intensive applications on the server side.
Unfortunately, client-side JavaScript does not support this architecture, not even web workers can be effective in such a case because, for example, you cannot manipulate the DOM inside a Web Worker.
This is where WebAssembly is a win.
What Is Yew and How Is It Similar to React?
Yew is a Rust Framework for creating web applications that compile to the WebAssembly target that is meant to run on the browser.
However, it is important to note that WebAssembly is cross-platform and can run outside the browser.
Yew implements things the React way i.e it has hooks just like in React functional components, uses a JSX-like syntax to structure content, implements state management, implements a routing library, you can pass props to components and also implements a Virtual DOM.
Rust as a language heavily relies on macros to accomplish abstracted functionalities.
In Yew, we shall use several macros such as html!(to write jsx) and function_component(to declare components).
Hands-on
We are assuming that Rust is installed in your system. In case you need to install, you can refer to our Rust blog.
Rust comes installed with rustup which is a tool meant for managing Rust versions, rustc which is the Rust compiler and cargo which is the package manager for Rust applications.
To get started with web assembly, we have to install the WebAssembly target using the command rustup target add wasm32-unknown-unknown.
Next we have to install trunk using cargo, the command is cargo install –locked trunk. The trunk package/crate will help us in serving our application and also assets.
We are also required to install cargo-generate using the command cargo install cargo-generate.
The cargo-generate package/crate will help us generate a Yew application using a template stored on a code repository like GitHub.
You can download the complete code of this implementation from our repository: https://github.com/workfall/workfall-yew-app.
We shall start by creating a Yew application from a provided template using the command cargo generate –git https://github.com/yewstack/yew-trunk-minimal-template.
This will prompt you for a project name and it will create a directory with the same name containing all the project files.
Folder Structure
The folder structure in src directory will be organized as follows (just by convention, feel free to organize it as you please):
Rust compiler recognizes mod.rs files as modules, therefore we’ll create a components module and a views module.
We have to declare the modules in main.rs so that they are available anywhere within our application.
Note: Every time you add a new component or view, you must register it in the respective module(mod.rs) using the syntax pub mod <file_name_without_extension>.
The example is shown below for the nav component
In the root folder, we can see some autogenerated files including a scss file that we shall use to style our application.
If you expand the dist folder, you will see the .wasm file and also a .js file whose main purpose is to load the .wasm file for use by the browser APIs.
It is not a transpiler WASM as someone may easily think.
Configuring Logging and Debugging in the Browser Console
When using JavaScript we can debug using the console by printing logs using the console.log() method.
For Yew, we have to configure a wasm logger to assist us with that purpose.
We have to add the following to our Cargo.toml: log = “0.4.6” and wasm-logger = “0.2.0”.
In the main.rs file add wasm_logger::init(wasm_logger::Config::default()); to the main function before the renderer.
To create console logs, you can now use the log::info!(“”); macro.
Handling Routing
We are going to configure our router in the app.rs file, but first let us add yew-router = “0.17” crate to our Cargo.toml
Then create at least a component (a navigation bar) and views(home, about, contact, faq) that we can route to.
app.rs:
We shall use a procedural macro to create a Route enum with the following syntax:
nav.rs:
Define a struct for nav items and create a state variable using the use_state hook which will be a vector of type NavItem.
nav.rs(2):
We shall use the .iter() method to return an iterator from the vector then we can create each nav item and then use .collect() to transform the iterator into a collection of “HTML” or rather JSX elements.
State Management
Yew has the use_state hook to manage the local state and goes further to implement state management using a sort of Context API in React.
It is always a good idea to centrally manage the state of your application to avoid prop drilling and the same applies to Yew.
We shall use a simple example that will track the state of a counter that registers effects from the home component.
app.rs:
We shall start by defining a struct for the global state.
For now, we shall start with a simple counter. Initialize the state using the use_reducer hook and set the counter to zero.
We shall set the counter state in the home component and consume this state in the other components using the use_context hook.
home.rs:
We shall create a click event handler for the increment button
The home view:
about.rs:
The about view:
Conclusion
In this blog, we explored how FAST one can create a Frontend App using Yew Framework. You must have noticed many similarities between Yew and React.
You have also learned that Yew supports state management using contexts and the local state as well.
We have also discussed how WebAssembly may excel in creating high-performance applications that might be CPU-intensive. We will come up with more such use cases in our upcoming blogs.
Meanwhile…
If you are an aspiring Rust Lover and want to explore more about the above topics, here are a few of our blogs for your reference:
- AWS is in love with RUST and you should be too!
- How to Create a REST API with Rust Rocket Framework and Diesel Middleware with PostgreSQL Database?
Stay tuned to get all the updates about our upcoming blogs on the cloud and the latest technologies.
Keep Exploring -> Keep Learning -> Keep Mastering
At Workfall, we strive to provide the best tech and pay opportunities to kickass coders around the world. If you’re looking to work with global clients, build cutting-edge products and make big bucks doing so, give it a shot at workfall.com/partner today!