{"id":13550272,"url":"https://github.com/schell/mogwai","last_synced_at":"2025-05-14T18:07:11.482Z","repository":{"id":36569037,"uuid":"220831764","full_name":"schell/mogwai","owner":"schell","description":"The minimalist, obvious, graphical, web application interface","archived":false,"fork":false,"pushed_at":"2024-11-08T02:10:59.000Z","size":7177,"stargazers_count":432,"open_issues_count":6,"forks_count":26,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-04-15T00:41:27.776Z","etag":null,"topics":["dom","frontend","html","mogwai","reactive","rust","ui","web"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/schell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"schell"}},"created_at":"2019-11-10T18:27:51.000Z","updated_at":"2025-02-21T21:29:01.000Z","dependencies_parsed_at":"2024-01-15T19:44:10.618Z","dependency_job_id":"4800f002-fd7c-49dc-bd3f-411b08459099","html_url":"https://github.com/schell/mogwai","commit_stats":{"total_commits":259,"total_committers":6,"mean_commits":"43.166666666666664","dds":0.05405405405405406,"last_synced_commit":"1d9e0f473f2a31a7539105d4e57a732ff7ac5f49"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schell%2Fmogwai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schell%2Fmogwai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schell%2Fmogwai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schell%2Fmogwai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schell","download_url":"https://codeload.github.com/schell/mogwai/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254198515,"owners_count":22030966,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dom","frontend","html","mogwai","reactive","rust","ui","web"],"created_at":"2024-08-01T12:01:30.948Z","updated_at":"2025-05-14T18:07:06.474Z","avatar_url":"https://github.com/schell.png","language":"Rust","readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003e\n      \u003cimg src=\"https://raw.githubusercontent.com/schell/mogwai/master/img/gizmo.svg\" /\u003e\n    \u003cbr /\u003e\n    mogwai\n  \u003c/h1\u003e\n\u003c/div\u003e\n\n\u003e **m**inimal, **o**bvious, **g**raphical **w**eb **a**pplication **i**nterface\n\n[![Crates.io][ci]][cl]\n\n[ci]: https://img.shields.io/crates/v/mogwai.svg\n[cl]: https://crates.io/crates/mogwai/\n\n`mogwai` is a view library for creating GUI applications.\nIt is written in Rust and runs in your browser and has enough functionality server-side\nto do rendering. It is an alternative to React, Backbone, Ember, Elm, Purescript, etc.\n\n- [goals](#goals)\n- [concepts](#concepts)\n- [example](#example)\n- [intro](#introduction)\n- [why](#why)\n- [beginning](#ok---where-do-i-start)\n- [cookbook](#cookbook)\n- [more examples](#more-examples)\n- [sponsor this project](#sponsorship)\n\n## goals\n\n* provide a declarative approach to creating and managing view nodes\n* encapsulate component state and compose components easily\n* explicate view mutation\n* be small and fast (aka keep it snappy)\n\n## concepts\nThe main concepts behind `mogwai` are\n\n* **sinks and streams instead of callbacks** \n\n  View events like click, mouseover, etc are sent through streams instead of invoking a callback. \n  Streams can be mapped, filtered and folded.\n\n* **widget views are dumb** \n\n  A view is just a struct that mutates the UI tree after receiving a message from a stream.\n  Views are constructed and nested using plain Rust functions or an RSX macro.\n\n* **widget logic is one or more async tasks that loop over event messages** \n\n  Widgets use asynchronous task loops that receive events from the view and send updates\n  to the view in response.\n\n## example\nHere is an example of a button that counts the number of times it has been clicked:\n\n```rust, no_run\nuse mogwai_dom::prelude::*;\n\n#[derive(Default)]\nstruct Button {\n    clicks: usize,\n    click: Output\u003c()\u003e,\n    text: Input\u003cString\u003e,\n}\n\nimpl Button {\n    /// Convert into a `ViewBuilder`\n    fn builder(mut self) -\u003e ViewBuilder {\n        rsx! (\n            button(on:click=self.click.sink().contra_map(|_: JsDomEvent| ())) {\n                // Using braces we can embed rust values in our UI tree.\n                // Here we're creating a text node that starts with the\n                // string \"Clicked 0 times\" which updates every time a\n                // message is received on the stream.\n                {(\"Clicked 0 times\", self.text.stream().unwrap())}\n            }\n        ).with_task(async move {\n            while let Some(()) = self.click.get().await {\n                self.clicks += 1;\n                self.text.set(if self.clicks == 1 {\n                    \"Clicked 1 time\".to_string()\n                } else {\n                    format!(\"Clicked {} times\", self.clicks)\n                }).await.unwrap();\n            }\n        })\n    }\n}\n\nlet btn = Button::default();\n// Get a sink to manually send events.\nlet mut click_sink = btn.click.sink();\n// Build the view to render in the browser\nlet view = Dom::try_from(btn.builder()).unwrap();\n// Attach it to the browser's DOM tree\nview.run().unwrap();\n\n// Spawn asyncronous updates\nwasm_bindgen_futures::spawn_local(async move {\n    // Queue some messages for the view as if the button had been clicked:\n    click_sink.send(()).await.unwrap();\n    click_sink.send(()).await.unwrap();\n    // view's html is now \"\u003cbutton\u003eClicked 2 times\u003c/button\u003e\"\n});\n```\n\n## introduction\nIf you're interested in learning more - please read the [introduction and\ndocumentation](https://docs.rs/mogwai-dom/0.1.0/mogwai_dom/an_introduction/index.html).\n\n## why\n* No vdom diffing keeps updates snappy and the implementation minimal\n* Async logic by default\n* Explicit mutation\n* `ViewBuilder` allows running on multiple platforms (web, ios, android, desktop, etc)\n\n`mogwai` uses streams, sinks, a declarative view builder and async\nlogic to define components and how they change over time.\n\nView mutation is explicit and happens as a result of views receiving messages, so there\nis no performance overhead from vdom diffing.\n\nIf you prefer a functional style of programming with lots of maps and folds -\nor if you're looking to go _vroom!_ then maybe `mogwai` is right for you :)\n\nPlease do keep in mind that `mogwai` is still in alpha and the API is actively\nchanging - PRs, issues and questions are welcomed. As of the `0.6` release we\nexpect that the API will be relatively backwards compatible.\n\n### made for rustaceans, by a rustacean\n`mogwai` is a Rust first library. There is no requirement that you have `npm` or\n`node`. Getting your project up and running without writing any javascript is easy\nenough.\n\n### benchmarketing\n`mogwai` is snappy! Here are some very handwavey and sketchy todomvc metrics:\n\n![mogwai performance benchmarking](img/perf.png)\n\n## ok - where do i start?\nFirst you'll need new(ish) version of the rust toolchain. For that you can visit\nhttps://rustup.rs/ and follow the installation instructions.\n\nThen you'll need [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/).\n\nFor starting a new mogwai project we'll use the wonderful `cargo-generate`, which\ncan be installed using `cargo install cargo-generate`.\n\nThen run\n```shell\ncargo generate --git https://github.com/schell/mogwai-template.git\n```\nand give the command line a project name. Then `cd` into your sparkling new\nproject and\n```shell\nwasm-pack build --target web\n```\nThen, if you don't already have it, `cargo install basic-http-server` or use your\nfavorite alternative to serve your app:\n```shell\nbasic-http-server -a 127.0.0.1:8888\n```\nHappy hacking! :coffee: :coffee: :coffee:\n\n## cookbook\n:green_book: [Cooking with Mogwai](https://zyghost.com/guides/mogwai-cookbook/index.html) is a series\nof example solutions to various UI problems. It aims to be a good reference doc but not a step-by-step tutorial.\n\n## group channel :phone:\nHang out and talk about `mogwai` in the support channel:\n\n* [direct link to element app](https://app.element.io/#/room/#mogwai:matrix.org)\n* invitation https://matrix.to/#/!iABugogSTxJNzlrcMW:matrix.org?via=matrix.org.\n\n## more examples please\nExamples can be found in [the examples folder](https://github.com/schell/mogwai/blob/master/examples/).\n\nTo build the examples use:\n```shell\nwasm-pack build --target web examples/{the example}\n```\n\nAdditional external examples include:\n- [mogwai-realworld](https://github.com/schell/mogwai-realworld/) A \"real world\" app implementation (WIP)\n- [the benchmark suite](https://github.com/schell/todo-mvc-bench/)\n- your example here ;)\n\n## sponsorship\nPlease consider sponsoring the development of this library!\n\n* [sponsor me on github](https://github.com/sponsors/schell/)\n","funding_links":["https://github.com/sponsors/schell","https://github.com/sponsors/schell/"],"categories":["Rust"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschell%2Fmogwai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschell%2Fmogwai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschell%2Fmogwai/lists"}