39 releases

Uses new Rust 2024

0.7.2 Jun 27, 2025
0.6.8 Oct 29, 2023
0.6.7 Mar 4, 2023
0.6.0-alpha Dec 31, 2022
0.0.1 Nov 28, 2019

#85 in GUI

Download history 1/week @ 2025-03-18 12/week @ 2025-05-06 35/week @ 2025-05-13 227/week @ 2025-06-17 157/week @ 2025-06-24 12/week @ 2025-07-01

396 downloads per month
Used in 3 crates (2 directly)

MIT license

95KB
1.5K SLoC


mogwai

minimal, obvious, graphical widget application interface

Crates.io

mogwai is a Rust crate for building GUI applications, primarily in the browser, with cross-platform capabilities.

Overview

mogwai simplifies web app development by addressing challenges with web-sys, focusing on:

  • Element creation and styling
  • Event handling
  • Server-side rendering and cross-platform support

It offers a minimalistic and transparent approach, allowing you to structure your app freely.

Key Concepts

  • View Construction: Use the rsx! macro for intuitive view building.
  • Event Handling: Events are futures, not callbacks.
  • Cross-Platform: Traits ensure operations are cross-platform, with room for specialization.
  • Idiomatic Rust: Widgets are Rust types

Example

Here's a button that counts clicks:

use mogwai::web::prelude::*;
use wasm_bindgen::prelude::*;

#[derive(ViewChild)]
pub struct ButtonClick<V: View> {
    #[child]
    wrapper: V::Element,
    on_click: V::EventListener,
    num_clicks: Proxy<u32>,
}

impl<V: View> Default for ButtonClick<V> {
    fn default() -> Self {
        let mut num_clicks = Proxy::<u32>::default();

        rsx! {
            let wrapper = button(
                style:cursor = "pointer",
                on:click = on_click
            ) {
                // When the `num_clicks` proxy is updated it will replace this node.
                {num_clicks(n => match *n {
                    1 => "Click again.".to_string(),
                    n => format!("Clicked {n} times."),
                })}
            }
        }

        Self {
            wrapper,
            on_click,
            num_clicks,
        }
    }
}

impl<V: View> ButtonClick<V> {
    pub async fn step(&mut self) {
        let _ev = self.on_click.next().await;
        self.num_clicks.modify(|n| *n += 1);
    }
}

#[wasm_bindgen(start)]
pub fn main() {
    let mut view = ButtonClick::<Web>::default();
    mogwai::web::body().append_child(&view);
    wasm_bindgen_futures::spawn_local(async move {
        loop {
            view.step().await;
        }
    });
}

Getting Started

  1. Install the Rust toolchain from https://rustup.rs/.
  2. Install trunk.
  3. Use cargo-generate to start a new project:
cargo install cargo-generate
cargo generate --git https://github.com/schell/mogwai-template.git
cd your_project_name
trunk serve --config Trunk.toml

Resources

Community

Join the conversation on Element or via Matrix.

Support

Consider sponsoring on GitHub to support development.

Dependencies

~1–4MB
~75K SLoC