Lemon — reactive native desktop UI in Rust.
Getting started
Most apps only need [run], [WindowConfig], [Cx], and the layout widgets
([Column], [Row], [Text], [Button], …) re-exported below.
use lemon::{run, Cx, WindowConfig};
use lemon::{Button, Column, Text};
fn app(cx: &Cx) -> lemon::element::Element {
let count = cx.use_signal(0i32);
let label = count.clone();
let inc = count.clone();
Column::new()
.child(Text::new(move || label.get().to_string()))
.child(Button::new("+").on_click(move || inc.update(|n| *n += 1)))
.into_element()
}
fn main() {
run(WindowConfig::default().title("Counter"), app);
}
How an update flows
- Your root function (
app) returns an [element::Element] tree built with builders. - [
Cx::use_signal] and dynamic [Text::new] closures subscribe to reactive state. - When state changes, the runtime diffs the previous tree against the new one and emits patches.
- The platform layer applies patches to a retained tree, runs layout (Taffy), then paints (Vello).
Keys and lists
Give stable .key(id) values to siblings that are inserted, removed, or reordered
(see the list_keyed example). Without keys, children are reconciled by index only.
Components
[Component::new] wraps a sub-view with its own [Cx] hooks. It currently takes a function
pointer (fn(&Cx) -> Element), not a capturing closure. For list rows with per-item state,
prefer keyed [Row] / [Column] children instead of capturing [Component]s.
Migrating from Box_
The generic flex container builder was renamed to [View] (and [Element::View]) because
Box clashes with [std::boxed::Box] in Rust. Update imports and matches:
| Before | After |
|---|---|
Box_::new() |
[View::new()] |
Element::Box_(…) |
Element::View(…) |
use …::{Box_, …} |
use …::{View, …} |
[Box_] remains available as a deprecated type alias for one release cycle. Roadmap issues
and older examples may still mention Box_; treat that name as [View].
Lower-level API
[Runtime], [RetainedTree], [layout_pass], and [paint_pass] are public for tests and
custom hosts; normal apps should use [run] and never touch those directly.