Open-Source Wikis

/

Bevy

/

Features

/

UI

bevyengine/bevy

UI

Bevy's UI stack: layout via taffy, widgets via bevy_ui_widgets, theming via bevy_feathers, and rendering via bevy_ui_render.

Stack

graph TD
    A[bevy_feathers<br/>themed widgets] --> B[bevy_ui_widgets<br/>widget primitives]
    B --> C[bevy_ui<br/>layout + nodes]
    C --> D[bevy_ui_render<br/>renderer]
    C -. inputs .-> E[bevy_input_focus]
    C -. inputs .-> F[bevy_picking]
    C -. text .-> G[bevy_text]

You can use any layer:

  • bevy_ui only — write your own widgets; full control.
  • bevy_ui + bevy_ui_widgets — get button/slider/checkbox behavior, do your own styling.
  • bevy_ui + bevy_feathers — get themed widgets out of the box; ship faster.

Layout: taffy and Node

A UI element is an entity with a Node component plus zero or more style components (BackgroundColor, BorderColor, BorderRadius, Outline). Children are added with ChildOf (the standard hierarchy relationship). Layout is flexbox via taffy.

commands.spawn((
    Node {
        width: Val::Percent(100.),
        height: Val::Percent(100.),
        justify_content: JustifyContent::Center,
        align_items: AlignItems::Center,
        ..default()
    },
    BackgroundColor(Color::BLACK),
)).with_children(|parent| {
    parent.spawn((
        Node { width: Val::Px(200.), height: Val::Px(80.), ..default() },
        BackgroundColor(Color::srgb(0.2, 0.6, 0.9)),
    ));
});

In PostUpdate, bevy_ui builds a taffy tree mirroring the entity hierarchy, asks taffy to compute layout, and writes the results back to ComputedNode and Transform. Then the UI renderer extracts the data.

Grid layout primitives are available alongside flexbox.

Inputs: focus and picking

Two systems handle UI input:

  • Focusbevy_input_focus tracks which entity owns keyboard input. UI widgets that handle text or accept Enter / Space / Tab register observers for keyboard events filtered by focus.
  • Pickingbevy_picking::UiPickingPlugin is a UI-aware backend that produces Pointer<Click>, Pointer<Drag>, etc., for UI nodes. Widgets respond to these events directly.

The widgets in bevy_ui_widgets wire both up correctly out of the box.

Theming: bevy_feathers

bevy_feathers is a higher-level layer that adds a theme (color tokens, font sizes, spacing) and a library of pre-styled widgets. The theme is a resource — change it at runtime to swap colors across all visible widgets via change detection.

If you don't want Feathers' look, build your own theme on top of bevy_ui_widgets directly.

Rendering

bevy_ui_render extracts the laid-out tree each frame and produces a TransparentUi render phase. Backgrounds, borders, images, gradients, box shadows, and text are all separate draw paths but share the same phase. Custom shaders are supported via UiMaterial.

UI renders into the camera specified by UiTargetCamera (defaulting to the primary window's camera). For multi-camera UI (split-screen, overlays per viewport), each camera gets its own UI tree.

Z-order

UI nodes have an implicit Z-order: later siblings render on top of earlier siblings, and the ZIndex component overrides this for specific entities. The stack computation is in crates/bevy_ui/src/stack.rs.

Common patterns

  • Container that fills the screenNode { width: Val::Vh(100.), height: Val::Vh(100.), ... }.
  • Centered contentjustify_content: Center, align_items: Center on the parent.
  • Aspect-ratio imageNode { aspect_ratio: Some(16. / 9.), ... }.
  • Scroll viewNode { overflow: Overflow::scroll_y(), ... } plus Scrollbar from bevy_ui_widgets.

Common pitfalls

  • Forgetting JustifyContent and AlignItems — flexbox defaults to start-aligned with no content distribution. Setting both to Center is the most common need.
  • Using Px everywhere — UI doesn't scale to different displays. Mix Val::Px, Val::Percent, and Val::Vh/Val::Vw for responsive layout.
  • Forgetting BackgroundColorNode alone is invisible.
  • UiTargetCamera — if no UI shows up after spawning into a non-primary camera, check this component is set.

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

UI – Bevy wiki | Factory