Expand description
Xilem is a UI toolkit. It combines ideas from Flutter, SwiftUI, and Elm.
Like all of these, it uses lightweight view objects, diffing them to provide
minimal updates to a retained UI. Like SwiftUI, it is strongly typed.
The talk Xilem: Let’s Build High Performance Rust UI by Raph Levien was presented at the RustNL conference in 2024, and gives a video introduction to these ideas. Xilem is implemented as a reactive layer on top of Masonry, a widget toolkit which is developed alongside Xilem. Masonry itself is built on top of a wide array of foundational Rust UI projects:
- Rendering is provided by Vello, a high performance GPU compute-centric 2D renderer.
- GPU compute infrastructure is provided by wgpu.
- Text layout is provided by Parley.
- Accessibility is provided by AccessKit (docs).
- Window handling is provided by winit.
Xilem can currently be considered to be in an alpha state. Lots of things need improvements (including this documentation!).
There is also a blog post from when Xilem was first introduced.
§Example
A simple incrementing counter application looks like:
use winit::error::EventLoopError;
use xilem::view::{Axis, text_button, flex, label};
use xilem::{EventLoop, WindowOptions, WidgetView, Xilem};
#[derive(Default)]
struct Counter {
num: i32,
}
fn app_logic(data: &mut Counter) -> impl WidgetView<Counter> + use<> {
flex(Axis::Vertical, (
label(format!("{}", data.num)),
text_button("increment", |data: &mut Counter| data.num += 1),
))
}
fn main() -> Result<(), EventLoopError> {
let app = Xilem::new_simple(Counter::default(), app_logic, WindowOptions::new("Counter app"));
app.run_in(EventLoop::with_user_event())?;
Ok(())
}A key feature of Xilem’s architecture is that the application’s state, in this case Counter, is an arbitrary 'static Rust type.
In this example, app_logic is the root component, which creates the view value it returns.
This, in turn, leads to corresponding Masonry widgets being created, in this case a button and a label.
When the button is pressed, the number will be incremented, and then app_logic will be re-ran.
The returned view will be compared with its previous value, which will minimally update the contents of these widgets.
As the num field’s value has changed, the label’s formatted text will be different.
This means that the label widget’s text will be updated, updating the value displayed to the user.
In this case, because the button is the same, it will not be updated.
More examples can be found in the repository.
Note: The linked examples are for the main branch of Xilem. If you are using a released version, please view the examples in the tag for that release.
§Reactive layer
The core concepts of the reactive layer are explained in Xilem Core.
§View elements
The primitives your Xilem app’s view tree will generally be constructed from:
flex: defines how items will be arranged in a row or columngrid: divides a window into regions and defines the relationship between inner elements in terms of size and positionsized_box: forces its child to have a specific width and/or heightsplit: contains two views splitting the area either vertically or horizontally which can be resized.button: basic button elementimage: displays a bitmap imageportal: a scrollable regionprogress_bar: progress bar elementprose: displays immutable, selectable texttext_input: allows text to be edited by the usertask: launch an async task which will run until the view is no longer in the treezstack: an element that lays out its children on top of each other
You should also expect to use the adapters from Xilem Core, including:
lens: an adapter for using a component from a field of the current state.memoize: allows you to avoid recreating views you know won’t have changed, based on a key.
§Precise Capturing
Throughout Xilem you will find usage of + use<> in return types, which is the Rust syntax for Precise Capturing.
This is new syntax in the 2024 edition, and so it might be unfamiliar.
Here’s a snippet from the Xilem examples:
fn app_logic(data: &mut EmojiPagination) -> impl WidgetView<EmojiPagination> + use<> {
// ...
}The precise capturing syntax in this case indicates that the returned view does not make use of the lifetime of data.
This is required because the view types in Xilem must be 'static, but as of the 2024 edition, when impl Trait is used
for return types, Rust assumes that the return value will use the parameter’s lifetimes.
That is a simplifying assumption for most Rust code, but this is mismatched with how Xilem works.
Re-exports§
pub use masonry;pub use masonry::dpi;pub use xilem_core as core;pub use tokio;pub use winit;
Modules§
- palette
- Palettes with predefined colors.
- style
- Traits used to set custom styles on views.
- view
- Views for the widgets which are built-in to Masonry. These are the primitives your Xilem app’s view tree will generally be constructed from.
Structs§
- Affine
- A 2D affine transform.
- Blob
- Shared data with an associated unique identifier.
- Exit
OnClose - State type used by
Xilem::new_simple. - Font
Weight - Visual weight class of a font, typically on a scale from 1.0 to 1000.0.
- Image
Brush - Describes the image content of a filled or stroked shape.
- Masonry
Driver - Pod
- A container for a yet to be inserted Masonry widget to be used with Xilem.
- PodWindow
- A newtype wrapper around
NewWindowfor implementingViewElement. - Vec2
- A 2D vector.
- ViewCtx
- A context type passed to various methods of Xilem traits.
- Window
Id - A unique and persistent identifier for a window.
- Window
Options - Attributes and callbacks of a window.
- Window
View - A view representing a window.
- Xilem
- Runtime builder.
Enums§
- Image
Format - Defines the pixel format of an image.
- Insert
Newline - When to insert a newline in a text area.
- Text
Align - Alignment of a layout.
Constants§
- ASYNC_
MARKER_ WIDGET - The
WidgetIdwhich async events should be sent to.
Traits§
- AppState
- The trait
Xilem::newexpects to be implemented for the state. - Widget
View - Widget
View Sequence - An ordered sequence of widget views, it’s used for
0..Nviews. SeeViewSequencefor more technical details.
Functions§
- async_
action - The action which should be used for async events.
- window
- A view representing a window.
Type Aliases§
- AnyWidget
View - A view which can have any underlying view type.
- Color
- A convenient alias for the color type used for
Brush. - Event
Loop - The type of the event loop used by Masonry.
- Event
Loop Builder - The type of the event loop builder used by Masonry.