• Stars
    star
    424
  • Rank 102,329 (Top 3 %)
  • Language
    Rust
  • Created about 5 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The minimalist, obvious, graphical, web application interface


mogwai

minimal, obvious, graphical web application interface

Crates.io

mogwai is a view library for creating GUI 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.

goals

  • provide a declarative approach to creating and managing view nodes
  • encapsulate component state and compose components easily
  • explicate view mutation
  • be small and fast (aka keep it snappy)

concepts

The main concepts behind mogwai are

  • sinks and streams instead of callbacks

    View events like click, mouseover, etc are sent through streams instead of invoking a callback. Streams can be mapped, filtered and folded.

  • widget views are dumb

    A view is just a struct that mutates the UI tree after receiving a message from a stream. Views are constructed and nested using plain Rust functions or an RSX macro.

  • widget logic is one or more async tasks that loop over event messages

    Widgets use asynchronous task loops that receive events from the view and send updates to the view in response.

example

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

use mogwai_dom::prelude::*;

#[derive(Default)]
struct Button {
    clicks: usize,
    click: Output<()>,
    text: Input<String>,
}

impl Button {
    /// Convert into a `ViewBuilder`
    fn builder(mut self) -> ViewBuilder {
        rsx! (
            button(on:click=self.click.sink().contra_map(|_: JsDomEvent| ())) {
                // Using braces we can embed rust values in our UI tree.
                // Here we're creating a text node that starts with the
                // string "Clicked 0 times" which updates every time a
                // message is received on the stream.
                {("Clicked 0 times", self.text.stream().unwrap())}
            }
        ).with_task(async move {
            while let Some(()) = self.click.get().await {
                self.clicks += 1;
                self.text.set(if self.clicks == 1 {
                    "Clicked 1 time".to_string()
                } else {
                    format!("Clicked {} times", self.clicks)
                }).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 it to the browser's DOM tree
view.run().unwrap();

// Spawn asyncronous updates
wasm_bindgen_futures::spawn_local(async move {
    // Queue some messages for the view as if the button had been clicked:
    click_sink.send(()).await.unwrap();
    click_sink.send(()).await.unwrap();
    // view's html is now "<button>Clicked 2 times</button>"
});

introduction

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

why

  • No vdom diffing keeps updates snappy and the implementation minimal
  • Async logic by default
  • Explicit mutation
  • ViewBuilder allows running on multiple platforms (web, ios, android, desktop, etc)

mogwai uses streams, sinks, a declarative view builder and async logic to define components and how they change over time.

View mutation is explicit and happens as a result of views receiving messages, so there is no performance overhead from vdom diffing.

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. As of the 0.6 release we expect that the API will be relatively backwards compatible.

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.

benchmarketing

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

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! β˜• β˜• β˜•

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:

more examples please

Examples can be found in the examples folder.

To build the examples use:

wasm-pack build --target web examples/{the example}

Additional external examples include:

sponsorship

Please consider sponsoring the development of this library!

More Repositories

1

steeloverseer

A file watcher and development tool.
Haskell
128
star
2

gelatin

A nice Haskell graphics API. There's always room for jello.
Haskell
40
star
3

varying

Continuously varying values, made easy :)
Haskell
40
star
4

apecs

An asyncronous and pleasant entity-component system for Rust
Rust
40
star
5

renderling

πŸ– A GPU driven real-time renderer, backed by wgpu
Rust
38
star
6

PureMVC-Plus-Plus

A MVC application architecture for C++, based off of the popular PureMVC
C++
35
star
7

odin

High level 2d game engine written in Haskell.
Haskell
30
star
8

reflex-sdl2

A minimal host for sdl2 based reflex apps.
Haskell
26
star
9

typograffiti

Just let me draw nice text already!
Haskell
22
star
10

old-gods

Old Gods Engine
Rust
20
star
11

dagga

DAG scheduler with nice constraint semantics
Rust
16
star
12

ixshader

A shallow embedding of the OpenGL Shading Language in Haskell
Haskell
15
star
13

moongraph

Rust library for scheduling, managing resources, and running DAGs πŸŒ™
Rust
14
star
14

editor

An experimental text editor using freetype2 and OpenGL. Written in Haskell.
Haskell
11
star
15

glucose

An API that wraps webgl and opengl
Haskell
11
star
16

aeson-tiled

Aeson instances for Tiled map editor types
Haskell
10
star
17

px-lang

px is an experimental, typed lambda calculus for _
Haskell
9
star
18

gristle

Like ixshader but ergonomic
Haskell
9
star
19

fe_web_dev_in_rust

Intro to Rust and frontend web development - the book!
Shell
8
star
20

crabslab

Slabcraft for crabs
Rust
8
star
21

renderable

Drop-in rendering resource management
Haskell
7
star
22

blocks

A game where blocks...are a part of the game.
Haskell
7
star
23

mogwai-realworld

RealWorld mogwai impl
Rust
6
star
24

kabukitheatre.bourtange

A fort defense game written in lisp in 30 days.
Common Lisp
5
star
25

mod

JS modules to aid in code separation and organization.
JavaScript
4
star
26

bang

A display list and event system for creating 2D HTML5 canvas apps.
JavaScript
4
star
27

mossy

A STLC generating GLSL
Haskell
4
star
28

todo-mvc-bench

A benchmarking suite for TodoMVC implementations
JavaScript
4
star
29

blocks-ios

Haskell iPhone Tetris Clone
Objective-C
4
star
30

Sublime-AS3

I've moved on to vim, so this project most likely will not be updated...A project building package for Sublime Text 2
Python
4
star
31

berry

Constraint based GUI for Rust
Rust
3
star
32

the-mutant

Don't fear the Mutant
Haskell
3
star
33

smugmugjsgallery

A smugmug javascript gallery
JavaScript
3
star
34

blenderScripts

my custom blender scripts
Python
3
star
35

broomdog

πŸ§ΉπŸ• Rust library providing a map of type-erased values with indefinite loanership semantics
Rust
3
star
36

haskellgames

haskellgames.com
Haskell
3
star
37

urzas-toolbox

A Haskell package for the game artificer.
Haskell
3
star
38

milkshake

Website CMS built with ❀️ and Haskell.
HTML
3
star
39

beginners-guide-msg-passing

A Beginner's Guide to Message Passing in Rust
JavaScript
2
star
40

mogwai-todo

MOVED TO
Rust
2
star
41

varying-tetris

Tetris implemented with varying and gelatin
Haskell
2
star
42

schells.tmbundle

my textmate bundle (has a bunch of stuff in it)
C
2
star
43

arborgeddon

Jake witnessed his family murdered by savage trees. Now's he's back for treevenge!
Haskell
2
star
44

pusher

A server for pushing things to s3.
Haskell
2
star
45

scottys-crew

Adds user sessions to scotty.
Haskell
2
star
46

gooey

User interfaces that are renderable, varying and eventually produce a value
Haskell
2
star
47

event-transformer

An ephemeral continuation monad in the form of an effectful Moore machine. Wut?
Haskell
2
star
48

mogwai-template

cargo generate template for mogwai
Rust
2
star
49

officialgingerandscott.com

Ginger Berglund and Scott Whitfield
Haskell
1
star
50

image-mapper

Image Mapping Tool
Haskell
1
star
51

mars

My terraform modules
HCL
1
star
52

ld31

Ludum Dare 31
Haskell
1
star
53

meshterial

Vulkan based 2d and 3d rendering system that supports some meshes
Rust
1
star
54

elxa

The BTC based bounty service.
Haskell
1
star
55

modmash.it

modmash.it website
1
star
56

aagol

another automaton game of life
JavaScript
1
star
57

drawn-quartered

A roguelike.
Haskell
1
star
58

shortygoldsteins

Shorty Goldstein's
Haskell
1
star
59

Mod-2

mod 2
Objective-C
1
star
60

todo_finder

Finds TODOs in your filesystem
Rust
1
star
61

deckprinter

Magic deck printer
1
star
62

glapp

My experimental editor.
Haskell
1
star
63

schell.github.com

Various things of mine
HTML
1
star
64

bindings-objc

Low level Haskell bindings to the Objective-C runtime.
Haskell
1
star
65

MachineMash

C++
1
star
66

slaughterballoon.com

slaughter balloon software company
PHP
1
star
67

self-pong

Pong by yourself! But really this is another sandbox for me.
Haskell
1
star
68

orion

Personal data tracking.
Haskell
1
star
69

illegal-text-reloc

Haskell
1
star
70

audaxian-toolbox

Gimme build web things!
Haskell
1
star
71

voxy

Foxy voxy.
Haskell
1
star
72

caltrops

Haskell
1
star
73

dotfiles

My dot files.
Emacs Lisp
1
star
74

wikifire

Contentinating the countryside
Haskell
1
star
75

dropdox

Use Fuse to manage Amazon S3 as a mounted filesystem
Haskell
1
star
76

nshaskell

High level library for building Mac and iOS applications in Haskell
Haskell
1
star
77

Mod-1

iOS modular synthesizer
Objective-C
1
star
78

esthree

A REPL for working with Amazon S3
Haskell
1
star
79

xybish

A simple UDP driven, in memory, key value store.
Haskell
1
star
80

gelatin-tutorial

WIP tutorial for the 2d rendering library gelatin and friends
Haskell
1
star
81

htmlbin

a bucket of html
1
star
82

germs

A kind of block cellular automata.
Haskell
1
star
83

exchange

My BTC exchange.
Haskell
1
star
84

Slice-Machine

The Slice Machine
Objective-C
1
star
85

ludum-helpers

A sandbox of helpful patterns for writing my Ludum Dare games in Haskell.
Haskell
1
star
86

teleform

IaC in a Rust library
Rust
1
star
87

rust-gpu-expo

Attempt to find exponential filesize / compile times in rust-gpu
Rust
1
star
88

pretzel

2D rendering library based on renderling and rust-gpu
Rust
1
star