egui
Immediate-mode GUIs in Rust with egui and eframe - fast iteration for tools, inspectors, and utilities.
Search across all documentation pages
Immediate-mode GUIs in Rust with egui and eframe - fast iteration for tools, inspectors, and utilities.
eframe::run_native(
"My Tool",
eframe::NativeOptions::default(),
Box::new(|cc| {
egui_extras::install_image_loaders(&cc.egui_ctx);
Ok(Box::new(MyApp::default()))
}),
)?;When to reach for this:
bevy_egui)struct MyApp {
name: String,
age: u32,
}
impl Default for MyApp {
fn default() -> Self {
Self {
name: "Alice".into(),
age: 30,
}
}
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Profile");
ui.text_edit_singleline(&mut self.name);
ui.add(egui::Slider::new(&mut self.age, 0..=120));
if ui.button("Greet").clicked() {
println!("Hello {}, age {}", self.name, self.age);
}
});
}
}What this demonstrates:
self each frameupdate -> layout widgets -> paint.Context requests repaint when animations or async data arrive.| Mode | egui | iced |
|---|---|---|
| Model | Rebuild UI each frame | Diff widget tree |
| Best for | Tools | Consumer apps |
update - drops frames. Fix: compute in background thread, poll results via channel.ui.push_id for dynamic lists.pixels_per_point appropriately.| Alternative | Use When | Don't Use When |
|---|---|---|
| iced | Elm architecture, native feel | Need HTML ecosystem |
| Tauri | Web designers on team | Want single-language UI |
| Slint | Declarative UI with design tool | Pure immediate-mode preference |
| GTK via gtk-rs | GNOME integration | Cross-platform identical UX |
eframe is fastest start; custom integration when embedding in game engine.
Visuals::dark() / light() or custom Spacing and Style on Context.
egui_plot crate for line/scatter charts inside same immediate-mode loop.
ctx.request_repaint() when background thread fills buffer; read under Mutex in update.
egui on Android/iOS possible but not primary focus - test touch targets carefully.
bevy_egui plugin for in-game overlays - see game development section.
Serialize state to JSON on exit - not automatic like retained UI frameworks.
Use consistent labels/ids in loops; Memory helper for window positions.
puffin or tracy integration; reduce widget count per panel.
See State & Architecture for larger apps.
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 16, 2026