An open API service indexing awesome lists of open source software.

https://github.com/mikolajbadyl/ruxlet

A GUI framework for Rust, powered by Flutter.
https://github.com/mikolajbadyl/ruxlet

cross-platform dart-ffi declarative-ui desktop elm elm-architecture ffi flutter gui gui-framework rust rust-lang

Last synced: 6 days ago
JSON representation

A GUI framework for Rust, powered by Flutter.

Awesome Lists containing this project

README

          

# ruxlet

[![ruxlet](https://img.shields.io/crates/v/ruxlet?label=ruxlet)](https://crates.io/crates/ruxlet)
[![ruxlet-cli](https://img.shields.io/crates/v/ruxlet-cli?label=ruxlet-cli)](https://crates.io/crates/ruxlet-cli)
[![CI](https://github.com/mikolajbadyl/ruxlet/actions/workflows/ci.yml/badge.svg)](https://github.com/mikolajbadyl/ruxlet/actions/workflows/ci.yml)
[![License](https://img.shields.io/crates/l/ruxlet)](LICENSE)

**Build desktop apps in pure Rust, rendered by Flutter.**

ruxlet gives you an Elm-style app model: your state, messages, views and side
effects all live in Rust. Flutter runs behind the scenes as the renderer, so you
get native-quality widgets without writing any Dart.

```text
Rust app -> UiNode -> ruxlet runtime -> Flutter renderer -> desktop window
```

- State lives in Rust.
- Messages are typed Rust enums.
- Views are `UiNode` trees.
- Side effects return `Cmd`.

## Quick start

Install the CLI, then scaffold and run an app:

```sh
cargo install ruxlet-cli
ruxlet new counter
cd counter
ruxlet run
```

The CLI installs a single `ruxlet` command. The first run builds your app,
downloads the matching renderer bundle and opens the window. You need a stable
Rust toolchain plus `curl` and `tar` for the renderer download.

## Example

A complete counter app:

```rust
use ruxlet::{App, Cmd, UiNode};

#[derive(Default)]
struct CounterApp {
count: i32,
}

#[derive(Clone)]
enum Msg {
Increment,
Decrement,
}

impl App for CounterApp {
type Msg = Msg;

fn view(&self) -> UiNode {
UiNode::column(vec![
UiNode::text(format!("Count: {}", self.count)),
UiNode::row(vec![
UiNode::button("-", Msg::Decrement),
UiNode::button("+", Msg::Increment),
]),
])
}

fn update(&mut self, msg: Msg) -> Cmd {
match msg {
Msg::Increment => self.count += 1,
Msg::Decrement => self.count -= 1,
}
Cmd::none()
}
}

fn app() -> CounterApp {
CounterApp::default()
}

ruxlet::export_c_abi!(app);
```

App crates build as dynamic libraries:

```toml
[lib]
crate-type = ["cdylib"]

[dependencies]
ruxlet = "0.2"
```

## Features

- Elm-style `App` with `view`, `update`, lifecycle hooks and typed message mapping.
- Async commands (`Cmd`) and timer subscriptions (`Sub`).
- A full widget set: layout, controls, display, styling and themes.
- Diffed UI updates with stable keys, so focus and cursor position survive rebuilds.
- Keyboard, pointer, hover, text input and control-change events.
- A single declarative window with title, size, resize limits and close control.
- Reusable components and composite widgets.

See [Widgets](docs/guide/widgets.md) for the full catalog.

## Documentation

- [Getting Started](docs/guide/getting-started.md)
- [Architecture](docs/guide/architecture.md)
- [Widgets](docs/guide/widgets.md)
- [Window](docs/guide/window.md)
- [Diagnostics](docs/guide/diagnostics.md)

API reference: [docs.rs/ruxlet](https://docs.rs/ruxlet).

For installing from git or a local checkout, updating, and renderer cache
management, see [Getting Started](docs/guide/getting-started.md).

## CLI

```sh
ruxlet new # scaffold a new app
ruxlet run # build and launch the app
ruxlet build # produce a standalone app directory
ruxlet update # update the renderer bundle
ruxlet renderer ... # inspect or install renderer bundles
```

`ruxlet --help` lists every command and flag.

## Platform status

| Platform | Status |
| ------------ | ------------------------- |
| Linux x64 | Released renderer bundle |
| Windows x64 | Released renderer bundle |
| macOS x64 | Released renderer bundle |
| macOS arm64 | Released renderer bundle |

## Repository layout

- `crates/ruxlet`: public Rust API, runtime, protocol and bridge.
- `crates/ruxlet-cli`: scaffolding, running, packaging and renderer cache.
- `crates/example_app`: a workspace example exercising the framework.
- `flutter_renderer`: the generic renderer shared by every ruxlet app.

Run the example from a checkout:

```sh
cargo run -p ruxlet-cli -- run --package example_app
```

## Contributing

Contributor rules live in [CLAUDE.md](CLAUDE.md). Before sending changes:

```sh
cargo fmt --check
cargo clippy --all-targets
cargo test
```

Flutter is only needed when working on `flutter_renderer` (`flutter analyze`).

## License

Apache License 2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE).