Mogwai is a view library for creating GUI applications in Rust. This innovative library runs in your browser and has enough server-side functionality to handle rendering, making it a robust alternative to popular frameworks like React, Backbone, Ember, Elm, and Purescript.
Goals of Mogwai
- Provide a declarative approach to creating and managing view nodes.
- Encapsulate component state and compose components easily.
- Explicate view mutation logically.
- Be small and fast, ensuring snappy performance.
Key Concepts of Mogwai
The core principles behind Mogwai focus on a few advanced concepts:
- Sinks and Streams: Instead of using callbacks, events like clicks and mouseovers are sent through streams, making it easy to manage and manipulate.
- Dumb Widget Views: Views are simple structs which modify the UI tree based on the messages they receive.
- Async Logic: Widgets utilize asynchronous task loops that handle events and send updates accordingly.
Example: Click Counter Button
Imagine you’re building a button that counts the number of times it has been clicked. Let’s explore how to create this using Mogwai:
use mogwai_dom::prelude::*;
#[derive(Default)]
struct Button {
clicks: usize,
click: Output(),
text: InputString,
}
impl Button {
// Converts into a ViewBuilder
fn builder(mut self) -> ViewBuilder {
rsx! (
button(on: click = self.click.sink().contra_map |_| JsDomEvent::default()) {
// Embedding rust values in UI tree
// Updates UI each time a message is received
(format!("Clicked {} times", self.clicks))
}
)
.with_task(async move {
while let Some(()) = self.click.get().await {
self.clicks += 1;
self.text.set(format!("Clicked {} time{}", self.clicks, if self.clicks == 1 { "" } else { "s" })).await.unwrap();
}
})
}
}
let btn = Button::default();
// Get a sink to manually send events
let mut click_sink = btn.click.sink();
// Build the view to render in the browser
let view = Dom::try_from(btn.builder()).unwrap();
// Attach to the browser's DOM tree
view.run().unwrap();
// Spawn asynchronous updates
wasm_bindgen_futures::spawn_local(async move {
// Simulating button clicks
click_sink.send(()).await.unwrap();
click_sink.send(()).await.unwrap();
});
// the view's html is now:
Understanding the Code with an Analogy
Think of the above code as a friendly bartender at a lively party who keeps track of how many drinks you have ordered. When someone orders a drink (clicks the button), the bartender counts it up for you. The bartender doesn’t think about how to keep track of people coming in and out of the party or what drink they want next—he simply waits for the order (click event) and responds by updating your drink count (displaying the updated HTML) every time he gets a new order. Just like our button—each click sends a signal that updates its internal state and reflects it back to the user.
Introduction to Mogwai
For those eager to delve deeper, please refer to the introduction and documentation.
Why Choose Mogwai?
Mogwai brings several benefits:
- No virtual DOM diffing means updates are snappy.
- Async logic is a default feature.
- Explicit mutation keeps your UI predictable.
- The ViewBuilder is versatile and runs across various platforms: web, iOS, Android, desktop, etc.
Getting Started with Mogwai
If you’re eager to start your journey with Mogwai, follow these simple steps:
- Make sure you have an updated version of the Rust toolchain. Visit rustup.rs for installation instructions.
- Install wasm-pack.
- Use cargo-generate to create a new Mogwai project:
- Run the following command in the shell:
- Navigate into your fresh project:
- Build your project:
- Finally, serve your application:
- Happy hacking!
cargo install cargo-generate
cargo generate --git https://github.com/schell/mogwai-template.git
cd
wasm-pack build --target web
cargo install basic-http-server
basic-http-server -a 127.0.0.1:8888
Cookbook for Mogwai
Looking for practical examples? The Mogwai Cookbook offers solutions to various UI problems, serving as a great reference.
Troubleshooting
If you encounter any issues while using Mogwai, here are some troubleshooting steps:
- Ensure your Rust toolchain is updated to the latest version.
- Check that all necessary libraries are installed correctly.
- If you run into specific errors, consult the project documentation for solutions.
For more insights, updates, or to collaborate on AI development projects, stay connected with fxis.ai.
At fxis.ai, we believe that such advancements are crucial for the future of AI, as they enable more comprehensive and effective solutions. Our team is continually exploring new methodologies to push the envelope in artificial intelligence, ensuring that our clients benefit from the latest technological innovations.

