[](https://gitlab.com/NeoRelm/NeoRelm/-/pipelines)
[](https://crates.io/crates/nrelm)
[](https://neorelm.gitlab.io/neorelm/nrelm/)

[](https://deps.rs/repo/gitlab/NeoRelm/NeoRelm)
[](https://matrix.to/#/#nrelm:matrix.org)
An idiomatic GUI library inspired by [Elm](https://elm-lang.org/) and based on [gtk3-rs](https://crates.io/crates/gtk).
**NeoRelm is a GTK3 port of [Relm4](https://gitlab.com/Relm4/Relm4)** (the original
[Relm4](https://gitlab.com/Relm4/Relm4) targets [GTK4](https://www.gtk.org/) and
[libadwaita](https://gitlab.gnome.org/GNOME/libadwaita), while this project backports the same
API and design to [GTK3](https://www.gtk.org/)).
Why? Because gnome keeps deprecating everything in gtk4. Making apps with gtk4 without libadwaita might not be easy in future. And because I wanted to make apps for [XFCE](https://xfce.org).
## Documentation
+ 📜 **[Documentation](https://neorelm.gitlab.io/neorelm/nrelm/)**
+ 🌐 **[The repository](https://gitlab.com/neorelm/neorelm)** — including examples and the changelog
## Dependencies
NeoRelm depends on GTK3
## Ecosystem
+ [nrelm-macros](https://crates.io/crates/nrelm-macros) - several macros for declarative UI definitions.
+ [nrelm-components](https://crates.io/crates/nrelm-components) - a collection of reusable components.
+ [nrelm-icons](https://gitlab.com/NeoRelm/NeoRelm-icons) - icons for your application (maintained in its own repository).
Use this in your `Cargo.toml`:
```toml
# Core library
nrelm = "0.1.1"
# Optional: reusable components
nrelm-components = "0.1.1"
# Optional: icons (more info at https://gitlab.com/NeoRelm/NeoRelm-icons)
nrelm-icons = "0.1"
```
### Features
The `nrelm` crate has two feature flags:
| `macros` | Enable macros by re-exporting [`nrelm-macros`](https://crates.io/crates/nrelm-macros) | ✅ |
| `css` | Enable the built-in CSS definitions of [`nrelm-css`](https://crates.io/crates/nrelm-css) | ✅ |
## Examples
Several example applications are available at [examples/](examples/).
#### [📸 Screenshots from the example apps](assets/screenshots)
### A simple counter app


```rust
use gtk::prelude::*;
use nrelm::prelude::*;
struct AppModel {
counter: u8,
}
#[derive(Debug)]
enum AppMsg {
Increment,
Decrement,
}
#[nrelm::component]
impl SimpleComponent for AppModel {
type Init = u8;
type Input = AppMsg;
type Output = ();
view! {
gtk::Window {
set_title: "Simple app",
set_default_size: (300, 100),
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 5,
set_margin_all: 5,
gtk::Button {
set_label: "Increment",
connect_clicked => AppMsg::Increment,
},
gtk::Button {
set_label: "Decrement",
connect_clicked => AppMsg::Decrement,
},
gtk::Label {
#[watch]
set_label: &format!("Counter: {}", model.counter),
set_margin_all: 5,
}
}
}
}
// Initialize the component.
fn init(
counter: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let model = AppModel { counter };
// Insert the code generation of the view! macro here
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
match msg {
AppMsg::Increment => {
self.counter = self.counter.wrapping_add(1);
}
AppMsg::Decrement => {
self.counter = self.counter.wrapping_sub(1);
}
}
}
}
fn main() {
let app = RelmApp::new("nrelm.example.simple");
app.run::<AppModel>(0);
}
```
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.
**Feedback and contributions are highly appreciated!**