# XenGui: a reactive GUI library in pure Rust
[<img alt="github" src="https://img.shields.io/badge/github-randseas/xengui-00aaaa?logo=github" height="20">](https://github.com/randseas/xengui)
[](https://crates.io/crates/xengui)
[](https://crates.io/crates/xengui)
[](https://www.rust-lang.org)
[](https://docs.rs/xengui)
[](https://github.com/randseas/xengui/blob/main/LICENSE)
<p align="start" style="margin-top: -.5rem">
<a href="https://xengui.vercel.app">
<img src="https://raw.githubusercontent.com/randseas/xengui/main/assets/XenGui_logo.svg" alt="XenGui logo" width="350"/>
</a>
</p>
<div align="start" style="margin-top: -1.5rem; text-decoration: underline; text-decoration-color: #4daafc;">
### [Live web demo](https://xengui.vercel.app)
</div>
---
> [!IMPORTANT]
> XenGui is currently an early development release. APIs are still evolving and may change without notice between versions. Use with caution in production projects and expect breaking changes until a stable `1.0.0` release.
## Features
- **Reactive state** - React-style hooks (`use_state`, `component`) drive re-renders without a virtual DOM diffing framework bolted on top.
- **Flexbox & Grid layout** - Full CSS-like layout via [`taffy`](https://github.com/DioxusLabs/taffy), including flex direction, wrapping, alignment, gaps, and grid tracks.
- **GPU-accelerated rendering** - Rects, text, and images are batched and drawn through dedicated `wgpu` pipelines.
- **Declarative styling** - A CSS-like `Style`/`StyleBuilder` API covering colors (including OKLCH), borders, typography, spacing, and more.
- **Built-in widgets** - `View`, `Label`, `Button`, and `Image`, each with hover/pressed/disabled style variants.
- **Interaction system** - Unified handling of hover, click, focus, and keyboard events across widgets.
- **Cross-platform** - Native targets (Windows, macOS, Linux) and WebAssembly from a single codebase.
## Example
```rust
Button::new()
.label("Increment")
.font_size(16)
.color(Color::NEUTRAL_500)
.background(Color::NEUTRAL_200)
.border(Border::new(1, Color::NEUTRAL_200, Length::px(8.0)))
.padding(Edges::only(9, 4, 9, 7))
.on_click(move |_ctx| set_counter.set(counter + 1))
.hover_style(|s|
s
.background(Color::NEUTRAL_200)
.border(Border::new(1, Color::NEUTRAL_300, Length::px(8.0)))
.color(Color::NEUTRAL_600)
);
```
## Installation
`Cargo.toml`
```toml
[dependencies]
xengui = "0.2.2"
```
## Sections
- [Example](#example)
- [Demo](#demo)
- [Quick Start](#quick-start)
- [Documentation](#documentation)
## Quick Start
```rust
use xengui::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = AppConfig {
title: "My XenGui App".into(),
width: 640,
height: 480,
position: WindowPosition::Center,
..Default::default()
};
let mut app = App::new(config);
app.render(|| {
let (counter, set_counter) = use_state::<i32>(0);
Box::new(
View::new()
.display(Display::Flex)
.flex_direction(FlexDirection::Column)
.align_items(AlignItems::Center)
.justify_content(JustifyContent::Center)
.width(Length::Percent(100.0))
.height(Length::Percent(100.0))
.background(Color::WHITE)
.child(
Label::new()
.label(format!("Count: {counter}"))
.font_size(20)
.color(Color::NEUTRAL_700)
)
.child(
Button::new()
.label("Increment")
.padding(Edges::symmetric(12, 8))
.background(Color::NEUTRAL_200)
.on_click(move |_ctx| set_counter.set(counter + 1))
)
)
});
app.run()?;
Ok(())
}
```
Run it with:
```bash
cargo run
```
For WebAssembly targets, build and serve with [Trunk](https://github.com/trunk-rs/trunk):
```bash
trunk serve
```
## Demo
Demo is available at: [https://xengui.vercel.app](https://xengui.vercel.app)
## Documentation
Docs are available at: [https://xengui.vercel.app/docs](https://xengui.vercel.app/docs)
## License
Apache License 2.0 © 2026 randseas. See [LICENSE](LICENSE) for details.