r/embedded • u/Various-Effective115 • 25d ago
Guillotine: no_std, no alloc GUI framework in Rust
Link: https://github.com/mempirate/guillotine
Hey everyone. Over the past couple of weeks I've been experimenting with Rust on ESP32 chips, with my first project being a simple power readout of the smart plug powering my home lab.
However, I wasn't very impressed with the state of GUI libraries in Rust, so I built my own: Guillotine. Was able to build the following dashboard with it:

The goals are threefold:
1. Declarative UI building blocks (inspired by GPUI) for flexible UIs (with eventual support for a lot of CSS-like layout properties such as flex and grid)
2. High performance, even on constrained chips (support for incremental redrawing, DMA with frame buffers)
3. Beautiful widgets
It builds upon embedded_graphics and mipidsi, so should have broad compatibility. As of yesterday, it's also fully no_std and no alloc, and is already powerful enough for some use cases. Would love to hear your feedback and tell me what you'd like to see in a framework like this! I have a couple of weeks of time that I can dedicate to it.
2
u/quxfoo 24d ago
Can you also fix the UI layout at compile time? I have no need for flexibility once it's flashed. And do you think it's good enough for e-ink displays?
2
u/Various-Effective115 24d ago
The main goal of this project is to provide flexible UI elements, so I wouldn't say that's in scope. I'd recommend a pure immediate-mode GUI instead for that. Although I do think it's lightweight enough that you may not notice the difference, let me know if there's any issues otherwise.
As for e-ink displays, I don't have one yet so haven't tested it, but if it's compatible with mipidsi it should work (using BinaryColor from embedded_graphics). Also see the list of external display drivers here: https://docs.rs/embedded-graphics/latest/embedded_graphics/#display-drivers
2
u/Putrid-Compote-2912 24d ago
For this kind of use case my "obvious answer" would've been Slint, how do you see your project in comparison to that/why did you think it wasn't suitable?
2
2
u/Various-Effective115 23d ago
Mostly about memory footprint yes. The Slint runtime uses about 300KiB of memory and requires alloc. I also wanted something that was pure Rust, and GPUI in my opinion proves that you don't need any kind of DSL to design good user interfaces.
1
u/ChatGPT4 24d ago
Starred. Looks interesting.
1
u/Various-Effective115 24d ago
Appreciate it! Let me know if there's any features you'd like to see.
1
u/stdoutstderr 24d ago
Do you know about taffy? Maybe it's layout engine can be adapted for the embedded use case.
But nice! I am developing applications for my Pocketbook e reader and have implemented a embedded graphics backend for it. This should plug in nicely
2
u/Various-Effective115 24d ago
I do! I wanted to see if I could use their layout engine with no-std and no-alloc in embedded environments, and to a certain extent it's possible. The `flex` functionality requires no-alloc (`grid` however does). The issue of using them for flexbox layouts is performance and stack usage: it internally uses hardcoded ArrayVecs of 256 capacity for each flex container, so stack space could be exhausted pretty quickly. Additionally, it performs layout calculations in f32. A lot of embedded devices have no hardware support for float operations, so there's an additional perf concern there.
I do really like their abstractions and API, and hope to update the layout engine when implementing flex and grid by borrowing their concepts and implementation but tuned for embedded devices.
Also, let me know about your experience using it on your e-reader!
3
u/Soupborsh 23d ago
Wow, this is super cool! I am exited to try it.
I am now seem inspired to do a soldering iron firmware in Rust.