Getting Started
From zero to window in about ninety seconds.
Prerequisites
- Rust nightly (Rinch uses a few unstable features —
let_chains, etc.) - A C/C++ compiler (Stylo has native dependencies)
- On Linux:
libfontconfig-devandpkg-config(for font discovery)
Create a Project
cargo new my-app
cd my-app
Add Rinch
# Cargo.toml
[dependencies]
rinch = { git = "https://github.com/joeleaver/rinch.git", features = ["desktop", "components", "theme"] }
What the features do:
"desktop"— windowing, event loop, software renderer. Required for desktop apps."components"— the 60+ component library (Button, TextInput, Modal, etc.)."theme"— CSS variable generation, color palettes, dark mode. Auto-enabled by"components"."gpu"— GPU rendering via Vello/wgpu instead of the software renderer. Optional."clipboard"— clipboard read/write. Optional."file-dialogs"— native open/save dialogs. Optional.
Write Your App
use rinch::prelude::*;
#[component]
fn app() -> NodeHandle {
let count = Signal::new(0);
rsx! {
Stack { gap: "md", p: "xl",
Title { order: 1, "Hello, Rinch!" }
Text { color: "dimmed", "Your first app. It only goes up from here." }
Group { gap: "sm",
Button { onclick: move || count.update(|n| *n += 1), "+" }
Button { variant: "outline", onclick: move || count.set(0), "Reset" }
}
Text { size: "xl", {|| format!("Count: {}", count.get())} }
}
}
}
fn main() {
run_with_theme("My App", 800, 600, app, ThemeProviderProps {
primary_color: Some("cyan".into()),
..Default::default()
});
}
Run It
cargo run --release
Always use
--releasefor running apps. Debug mode is slow because Stylo and Parley do serious work. Release builds are fast.
You should see a window with a title, description, two buttons, and a count that updates when you click “+”.
What Just Happened
#[component]injected a__scope: &mut RenderScopeparameter. You never see it, butrsx!needs it.rsx!built a DOM tree: created elements, set attributes, wired event handlers.{|| format!("Count: {}", count.get())}created an Effect that readscountand updates a text node. Whencountchanges, that closure re-runs and updates only that text node.run_with_themeopened a window, loaded theme CSS, mounted the component, and started the event loop.
Your app function ran exactly once. It will never run again. The closures handle everything from here.
What’s Next
- RSX Syntax — The full macro syntax: elements, attributes, events, control flow.
- State Management — Signals, Memos, Stores, Context.
- Components — The full component library.
- Theming — Colors, dark mode, CSS variables.
- Writing Components — Build your own.
- WASM — Run in the browser.