bevy_immediate: Immediate Mode UI for Bevy
A simple, fast, and modular UI library for Bevy, combining immediate mode ergonomics with Bevy ECS-powered retained UI.
- Write complex UI logic as simple Rust code.
- No macros, observers, triggers, events, signals.
- Focus on your UI, not the boilerplate.
Features
- Immediate mode entity hierarchy management
Build interactive entity hierarchies with a clean API. - Custom extension support
Add custom capabilities like.clicked()
,.selected(true)
,.hovered()
. Extension use integrated with rust type system for IDE and compile check support. - Inbuilt support for UI use case
Contains extensions that implement necessary logic for constructing UI. - Reusable widgets
Implement widgets using functional or bevy native style. - Fast
Only visits each entity once per tick and does minimal amount of changes. Heavy lifting is done by Bevy's retained UI. - Parallelizable
Minimal data access requirements allow systems to run in parallel with other systems without exclusive world access. - Simple
Define UI in straightforward functions, free from macro/observer/trigger boilerplate. - Modular
Extend the API with your own small capabilities and traits that encapsulate complex logic. - Integration-friendly
Works with other libraries (e.g., reloadable CSS style with bevy_flair). - Hot reloading support
Can be added via hot_lib_reloader.
⚠️ Note: This library is under active development. Expect some breaking changes, but they will be minimized.
Version compatibility
bevy_immediate | bevy | MSRV |
---|---|---|
0.1 | 0.16 | 1.85 |
To use add bevy_immediate
to your project dependencies in Cargo.toml
file.
See CHANGELOG for changes between versions.
Examples
- Hello world - Minimal usage example
- Power user - Customized API for complex use cases
- Plain UI - Create your UI as a single system
- Reusable widgets
- Functional widget - Implement widgets as plain functions
- Native widget - Implement native Bevy-like widgets
- Widget use - Use functional and native widgets together
- Menu example - Build a simple menu with selectable buttons
- Extensions
- Extension implementation - Write your own capabilities (e.g.
.clicked()
or.selected(...)
) - Using extensions - Use a custom predefined set of extensions
- Extension implementation - Write your own capabilities (e.g.
- Style - Simple example how to apply custom styles to UI
Check out ./examples/
(cargo run --example demo
).
Menu example
Example with code reuse and interactive elements:
;
;
pub const MENU_VARIANTS: = ;
Power user example
Here's a more advanced example where user has added their own API.
;
;
Extend functionality by implementing new capability
You can add new capabilities with just a few lines of code.
Here’s how .selected(...)
is implemented.
/// Implements capability to mark entities as selectable.
;
/// Marks component as being selectable
/// Implements methods to set entity selectable
FAQ
UI nodes are changing order and not correctly laid out
Make sure that you assign unique id using ch_id
for ui nodes that
can appear, disappear.
How do I avoid collisions with resources or queries in my systems?
- Queries: Add
Without<ImmMarker<Caps>>
to your query filter. - Resources: Avoid direct conflicts, or use .ctx() / .ctx_mut() APIs to access resources used by capabilities.
Contributing
Contributions are welcome!
- Add your improvements to examples
- Suggest or implement new capabilities useful for UI creation
Publish your own crate that is built using bevy_immediate
!
Inspiration
- Originally created for Settletopia
- Inspired by egui_taffy.
- Initial idea discussion
Future work
-
Easier definition of new capability sets
- Tried transitive capability implementation (works only inside one crate)
- Tried transitive trait implementation (works only inside one crate)
- Tried TupleList approach (conflicting trait implementations)
Therefore currently to define capability set users need to list all used capabilities.
-
Improve examples
- Add Example for hot reloading
-
Create reusable logic for:
- Scroll areas
- Tooltips
- Windows (like
egui::Window
)