Crate xilem

Crate xilem 

Source
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 column
  • grid: divides a window into regions and defines the relationship between inner elements in terms of size and position
  • sized_box: forces its child to have a specific width and/or height
  • split: contains two views splitting the area either vertically or horizontally which can be resized.
  • button: basic button element
  • image: displays a bitmap image
  • portal: a scrollable region
  • progress_bar: progress bar element
  • prose: displays immutable, selectable text
  • text_input: allows text to be edited by the user
  • task: launch an async task which will run until the view is no longer in the tree
  • zstack: 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.
ExitOnClose
State type used by Xilem::new_simple.
FontWeight
Visual weight class of a font, typically on a scale from 1.0 to 1000.0.
ImageBrush
Describes the image content of a filled or stroked shape.
MasonryDriver
Pod
A container for a yet to be inserted Masonry widget to be used with Xilem.
PodWindow
A newtype wrapper around NewWindow for implementing ViewElement.
Vec2
A 2D vector.
ViewCtx
A context type passed to various methods of Xilem traits.
WindowId
A unique and persistent identifier for a window.
WindowOptions
Attributes and callbacks of a window.
WindowView
A view representing a window.
Xilem
Runtime builder.

Enums§

ImageFormat
Defines the pixel format of an image.
InsertNewline
When to insert a newline in a text area.
TextAlign
Alignment of a layout.

Constants§

ASYNC_MARKER_WIDGET
The WidgetId which async events should be sent to.

Traits§

AppState
The trait Xilem::new expects to be implemented for the state.
WidgetView
WidgetViewSequence
An ordered sequence of widget views, it’s used for 0..N views. See ViewSequence for more technical details.

Functions§

async_action
The action which should be used for async events.
window
A view representing a window.

Type Aliases§

AnyWidgetView
A view which can have any underlying view type.
Color
A convenient alias for the color type used for Brush.
EventLoop
The type of the event loop used by Masonry.
EventLoopBuilder
The type of the event loop builder used by Masonry.