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_uionly — 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:
- Focus —
bevy_input_focustracks which entity owns keyboard input. UI widgets that handle text or accept Enter / Space / Tab register observers for keyboard events filtered by focus. - Picking —
bevy_picking::UiPickingPluginis a UI-aware backend that producesPointer<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 screen —
Node { width: Val::Vh(100.), height: Val::Vh(100.), ... }. - Centered content —
justify_content: Center, align_items: Centeron the parent. - Aspect-ratio image —
Node { aspect_ratio: Some(16. / 9.), ... }. - Scroll view —
Node { overflow: Overflow::scroll_y(), ... }plusScrollbarfrombevy_ui_widgets.
Common pitfalls
- Forgetting
JustifyContentandAlignItems— flexbox defaults to start-aligned with no content distribution. Setting both toCenteris the most common need. - Using
Pxeverywhere — UI doesn't scale to different displays. MixVal::Px,Val::Percent, andVal::Vh/Val::Vwfor responsive layout. - Forgetting
BackgroundColor—Nodealone is invisible. UiTargetCamera— if no UI shows up after spawning into a non-primary camera, check this component is set.
See also
bevy_uifor layout and core node types.bevy_ui_renderfor the renderer.bevy_ui_widgetsfor widget primitives.bevy_feathersfor the themed widget set.bevy_textfor text in UI.- Picking, Input.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.