All Projects → schell → Mogwai

schell / Mogwai

The minimalist, obvious, graphical, web application interface

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Mogwai

Crab
JavaScript library for building user interfaces with Custom Elements, Shadow DOM and React like API
Stars: ✭ 22 (-91.16%)
Mutual labels:  frontend, dom
Nipplejs
🎮 A virtual joystick for touch capable interfaces.
Stars: ✭ 1,313 (+427.31%)
Mutual labels:  frontend, dom
Tarant
Reactive, actor based framework that can be used in client and server side.
Stars: ✭ 33 (-86.75%)
Mutual labels:  reactive, frontend
Kvision
Object oriented web framework for Kotlin/JS
Stars: ✭ 658 (+164.26%)
Mutual labels:  reactive, frontend
Marko
A declarative, HTML-based language that makes building web apps fun
Stars: ✭ 10,796 (+4235.74%)
Mutual labels:  frontend, dom
Sinuous
🧬 Light, fast, reactive UI library
Stars: ✭ 740 (+197.19%)
Mutual labels:  reactive, dom
Elementx
⚡️ Functionally create DOM elements and compose them to a tree quickly
Stars: ✭ 62 (-75.1%)
Mutual labels:  frontend, dom
Imba
🐤 The friendly full-stack language
Stars: ✭ 5,434 (+2082.33%)
Mutual labels:  frontend, dom
Interview Problem Summary
🎤 Prepare for the interviews and sum up the most popular interview problems for front-end(HTML/CSS/Javascript), Web development, full-stack. Also did some typical coding practice questions, such as UI caculator
Stars: ✭ 112 (-55.02%)
Mutual labels:  frontend, dom
Cyclow
A reactive frontend framework for JavaScript
Stars: ✭ 105 (-57.83%)
Mutual labels:  reactive, frontend
Nanohtml
🐉 HTML template strings for the Browser with support for Server Side Rendering in Node.
Stars: ✭ 651 (+161.45%)
Mutual labels:  frontend, dom
Vue.py
Pythonic Vue.js
Stars: ✭ 223 (-10.44%)
Mutual labels:  reactive, frontend
Displayjs
A simple JavaScript framework for building ambitious UIs 😊
Stars: ✭ 590 (+136.95%)
Mutual labels:  frontend, dom
Zeroclipboard
The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.
Stars: ✭ 6,650 (+2570.68%)
Mutual labels:  frontend, dom
Reactive Interaction Gateway
Create low-latency, interactive user experiences for stateless microservices.
Stars: ✭ 465 (+86.75%)
Mutual labels:  reactive, frontend
Scalajs Bootstrap
Scala.js bootstrap components
Stars: ✭ 55 (-77.91%)
Mutual labels:  reactive, dom
Fritz2
Easily build reactive web-apps in Kotlin based on flows and coroutines.
Stars: ✭ 308 (+23.69%)
Mutual labels:  reactive, frontend
Ply
CSS inspection aided by visual regression pruning
Stars: ✭ 370 (+48.59%)
Mutual labels:  frontend, dom
Viewi
Powerful tool for building full-stack and completely reactive user interfaces using PHP
Stars: ✭ 93 (-62.65%)
Mutual labels:  reactive, frontend
Mag.js
MagJS - Modular Application Glue
Stars: ✭ 157 (-36.95%)
Mutual labels:  reactive, dom


mogwai

minimalist, obvious, graphical web application interface

release: Crates.io cicd

master: cicd

mogwai is a frontend DOM library for creating web applications. It is written in Rust and runs in your browser and has enough functionality server-side to do rendering. It is an alternative to React, Backbone, Ember, Elm, Purescript, etc.

toc

goals

  • provide a declarative approach to creating and managing DOM nodes
  • encapsulate component state and compose components easily
  • explicate DOM updates
  • be small and fast (snappy af)

If mogwai achieves these goals, which I think it does, then maintaining application state, composing widgets and reasoning about your program will be easy. Furthermore, your users will be happy because their UI is snappy!

concepts

The main concepts behind mogwai are

  • channels instead of callbacks - view events like clicks, blurs, etc are transmitted into a channel instead of invoking a callback. Receiving ends of channels can be branched and may have their output messages be mapped, filtered and folded. mogwai's channels are many-producer, many-consumer and are immediate - they do not perform buffering and do not require polling.

  • views are dumb - a View is just a bit of DOM that receives and transmits messages. When a View goes out of scope and is dropped in Rust, it is also dropped from the DOM. Views may be constructed and nested using plain Rust functions or an RSX macro.

  • widgets are folds over input messages - the user interface widget in mogwai is a Gizmo. The Gizmo type holds an internally mutable state and can communicate messages to its View, which may live out in the DOM. Its View can send messages back to the Gizmo, which triggers the Gizmo's update function. The Gizmo's update function can mutate the state variable and send output messages to the View, which in turn updates the DOM.

  • communication is easy - just gizmo.send(&my_message) to send a message into a gizmo and the gizmo will run its update logic and patch the view accordingly.

example

Here is an example of a button that counts the number of times it has been clicked:

use mogwai::prelude::*;

pub struct Button {
    pub clicks: i32
}

#[derive(Clone)]
pub enum ButtonIn {
    Click
}

#[derive(Clone)]
pub enum ButtonOut {
    Clicks(String)
}

impl Component for Button {
    type ModelMsg = ButtonIn;
    type ViewMsg = ButtonOut;
    type DomNode = HtmlElement;

    fn update(
        &mut self,
        msg: &ButtonIn,
        tx_view: &Transmitter<ButtonOut>,
        _subscriber: &Subscriber<ButtonIn>
    ) {
        match msg {
            ButtonIn::Click => {
                self.clicks += 1;
                let text = if self.clicks == 1 {
                    "Clicked 1 time".to_string()
                } else {
                    format!("Clicked {} times", self.clicks)
                };
                tx_view.send(&ButtonOut::Clicks(text))
            }
        }
    }

    // Notice that the `Component::view` function returns a `ViewBuilder<T>` and not
    // a `View<T>`.
    fn view(
        &self,
        tx: &Transmitter<ButtonIn>,
        rx: &Receiver<ButtonOut>
    ) -> ViewBuilder<HtmlElement> {
        let tx_event = tx.contra_map(|_:&Event| ButtonIn::Click);
        let rx_text = rx.branch_map(|ButtonOut::Clicks(text)| text.clone());

        builder!(
            // Create a button that transmits a message into tx_event on click.
            <button on:click=tx_event>
                // Using braces we can embed rust values in our DOM.
                // Here we're creating a text node that starts with the
                // string "Clicked 0 times" and then updates every time a
                // message is received on rx_text.
                {("Clicked 0 times", rx_text)}
            </button>
        )
    }
}
// To create a new gizmo/widget/component we simply convert a value of the Button type
// into a Gizmo...
let gizmo = Gizmo::from(Button{ clicks: 0 });
// ...and create a View from that gizmo's builder.
let view = View::from(gizmo.view_builder());
// Queue some messages for the component, as if the button had been clicked:
gizmo.send(&ButtonIn::Click);
gizmo.send(&ButtonIn::Click);

assert_eq!(&view.html_string(), "<button>Clicked 2 times</button>");

if cfg!(target_arch = "wasm32") {
    // running a view adds its DOM to the document.body and ownership is passed to the window,
    // so this only works in the browser
    view.run().unwrap_throw()
}

// After handing off the view the gizmo itself may fall out of scope and be dropped. The
// view is all that is needed for your app to run.

introduction

If you're interested in learning more - please read the introduction and documentation.

why

Rust is beginning to have a good number of frontend libraries. Many encorporate a virtual DOM with a magical update phase. Even in a language that has performance to spare this step can cause unwanted slowness and can be hard to reason about what is updating, exactly.

In mogwai, channel-like primitives and a declarative view builder are used to define components and then wire them together. Once the interface is defined and built, the channels are effectively erased and it's functions all the way down. There's no performance overhead from vdom, shadow dom, polling or patching. So if you prefer a functional style of programming with lots of maps and folds - or if you're looking to go vroom! then maybe mogwai is right for you :)

Please do keep in mind that mogwai is still in alpha and the API is actively changing - PRs, issues and questions are welcomed.

made for rustaceans, by a rustacean

mogwai is a Rust first library. There is no requirement that you have npm or node. Getting your project up and running without writing any javascript is easy enough.

performance

mogwai is snappy! Here is some very handwavey and sketchy todomvc benchmarketing:

mogwai performance benchmarking

ok - where do i start?

First you'll need new(ish) version of the rust toolchain. For that you can visit https://rustup.rs/ and follow the installation instructions.

Then you'll need wasm-pack.

For starting a new mogwai project we'll use the wonderful cargo-generate, which can be installed using cargo install cargo-generate.

Then run

cargo generate --git https://github.com/schell/mogwai-template.git

and give the command line a project name. Then cd into your sparkling new project and

wasm-pack build --target web

Then, if you don't already have it, cargo install basic-http-server or use your favorite alternative to serve your app:

basic-http-server -a 127.0.0.1:8888

Happy hacking! ☕️ ☕️ ☕️

more examples please

For more examples, check out

the sandbox

the todomvc app

the benchmark suite

To build the examples use:

cd examples/whatever && wasm-pack build --target web

external examples

mogwai-realworld A "real world" app implementation (WIP)

cookbook

📗 Cooking with Mogwai is a series of example solutions to various UI problems. It aims to be a good reference doc but not a step-by-step tutorial.

group channel ☎️

Hang out and talk about mogwai in the support channel:

sponsorship

Please consider sponsoring the development of this library!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].