Guillotine
A no-std graphical user interface framework for embedded devices prioritizing resource efficiency and ergonomics. The UI declaration API is heavily inspired by GPUI.
Works everywhere embedded-graphics works.
Demo
A demo Guillotine UI on a Waveshare ESP32-C6 1.47" LCD board from the shellyctl project:

Quickstart
use ;
use *;
Core Concepts
Declarative Definition
- Explain the idea of declaratively building your UI
Status: implemented ✅
Hybrid Immediate & Retained Mode
Status: unimplemented ❌
Similar tree-based layout to X
- GPUI
Status: implemented ✅
State Management
Layout Engine
- Conceptually similar to Flutter (i.e. constraints go down, sizes go up)
- constraints flow downward, sizes flow upward, positions flow downward
- Requirement: single pass.
Status: implemented ✅
API
use ;
use *;
Element trees use the display's PixelColor type throughout. Rgb565 views keep the API shown
above; other targets select their color once at the Render<Color> boundary, after which element
constructors and style methods infer it. See the binary-color example.
Insets and the box model
Margin, padding, and border widths accept CSS-like physical-edge shorthands:
cx.column
.margin // all edges
.padding // vertical, horizontal
.border // top, horizontal, bottom
.margin; // top, right, bottom, left
Use Insets::new(top, right, bottom, left) when a named value is clearer. Insets are non-negative
pixel lengths. Guillotine doesn't currently support percentages, auto, logical edges, negative
margins, margin collapsing, per-edge border colors, or border styles. Adjacent margins in rows and
columns add together.
Style::size is the border-box size: padding and border are placed inside it, and margin is added
outside it. The box grows to contain its padding and border when parent constraints allow.
Examples
To run the examples, you need to enable the simulator feature. This pulls in a bundled sdl2 for opening windows. You will need cmake to compile it.
Roadmap
v0.0.1
- Try to mimic GPUI declaration style: https://github.com/zed-industries/zed/blob/main/crates/gpui/examples/hello_world.rs
- Low-level
Element/ParentElementtrait for custom elements and widgets - Support generic
PixelColor - Full immediate mode redrawing
- Make repo ready for publishing:
- README documentation (a la Dioxus)
- Rustdoc documentation
- Examples
- Sizing (insets)
- Fonts
- Cool
- ESP32
- Fix exports
- Dual Apache / MIT license
- Fix sdl2 vendoring for embedded-graphics-simulator
-
TextStylefonts - Support for non-interactive elements:
- Row
- (formatted) Text
- Column
v0.1.0
- Add memory usage for examples
- cargo binutils for examples in CI (cargo size). This will detect regressions.
- No alloc
- Documentation
- Guide for finding the ideal
FrameStoragecapacity.
- Guide for finding the ideal
- Benchmarks for Frame building
- Container gaps (flex from CSS)
- Custom render modes feature:
incremental. Turned on by default. Will use more memory to manage tree in between frames. - Define inremental redrawing triggers / states:
- New elements
- Dialogs / Modals (floating containers)
- Charts
- Spinner
- Overflow behaviour:
- Visible
- Clip
-
profilefeature withdefmtlogs - Custom elements
- Alignment
- Support for interaction
- Support interactive elements:
- Button
- Slider
Why?
I was trying to build a clean-looking dashboard on a small LCD screen powered by an ESP32-C6, that's supposed to monitor and display the power consumption of my home lab (project here). I wanted to do this in Rust, with the esp-rs ecosystem. The ecosystem is quite mature, but I couldn't really find a UI framework that was:
- Performant
- Very low memory footprint (no Slint / LVGL)
- Beautiful
Additionally, I wanted to learn what it would take to build something like this.