egui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
Try it now: https://www.egui.rs/
egui development is sponsored by Rerun, a startup building an SDK for visualizing streams of multimodal data.
Highlights ✨
Emoji and glyph support
egui can now render any glyph that is supported on your system, including colored emojis and non-Latin scripts.
To enable this, the integration has to use one of two APIs:
Context::add_glyph_rasterizer(GlyphRasterizer): aGlyphRasterizerrenders a single glyph.eframeuses this on web to render individual glyphs to an off-screen canvas #8490, #8545.Context::add_font_provider(Arc<dyn FontProvider>): lets egui find and load whole fonts at runtime. Nativeeframeuses this through the newegui_system_font_providercrate, which lists system fonts withfontique#8512.
Completion popup
We've added a new CompletionPopup widget that adds autocomplete to a TextEdit.
You can use it e.g. to add emoji selection like in discord:
Screen.Recording.2026-10-15.at.16.05.41.mov
Experimental theme customizations
This release adds a theme plugin system #8153 by @AdrienZianne. Enable the new experimental feature flag, and there will be a
new StyleProvider trait, which can be used to customize visuals for a widget based on the provided classes.
/// Implement the trait for each Widget you'd like to customize
impl StyleProvider<ButtonStyle> for MyTheme {
fn style(&mut self, args: &StyleArgs<'_>) -> ButtonStyle {
// You could construct ButtonStyle from scratch, or extend eguis built in style:
let mut style: ButtonStyle = DefaultStyle.style(args);
if args.has_class("primary") {
style.atom_layout.frame.fill = hex_color!("#FF0000");
}
style
}
}
/// Register all your custom style providers
fn init(ctx: &Context) {
ctx.add_widget_theme::<ButtonStyle>(MyTheme);
ctx.add_widget_theme::<CheckboxStyle>(MyTheme);
// ...
}Record videos of integration tests
Reading an integration test to understand what its doing can be challenging, so we've added a egui_kittest/video
feature that records a mp4 video from it, using ffmpeg! Enable it and pass EGUI_KITTEST_RECORD=1 or EGUI_KITTEST_RECORD=open,
and a video of the test will be recorded. This is an example from one of our more complex rerun integration tests:
drop_stream_to_view__test_drop_multiple_streams_to_view_1.mp4
Improved accessibility
-
Better popup, menu, modal and panel trees #8581.
-
AccessKit support on panel resize handles #8578 by @YuEfSaEDU.
-
WidgetTypeis replaced withaccesskit::Role(re-exported asegui::Role) #8555. -
New
Response::accessible_name,Ui::label_inputs_by/Ui::name_inputs, andArea::role#8604, #8608, #8612. -
Invisible widgets are now hidden from the accessibility tree #8621.
-
Improved arrow key navigation within menus #8548 by @pederbe
Screen.Recording.2026-10-15.at.15.29.08.mov
Other
- Paste images from the clipboard:
Event::PasteImage#8472 by @BernardDGS. Alignedcontainer, e.g. for centering a group of widgets #8540CompletionPopupfor code completion over aTextEdit#8529RangeSlider#8580 by @gavrelina- Atoms:
AtomLayoutis split intoWidgetAtomandContainerAtom#8222. - Some style tweaks: roomier buttons and a larger corner radius #8617, #8445.
- Nicer kinetic scrolling with rubber-banding on overshoot #8662, #8663
⚠️ Breaking changes
default_fontsis no longer a default feature #8583.ViewportCommand::Screenshotnow uses a callback #8489.Id::new,AsIdandFrom<&str> for Idare all deprecated #8534, #8586.- New:
Id::unique,IdSaltSet,IdSaltMap#8534, #8590. Panelconstructors takeimpl AsIdSalt#8592.
⭐ Added
- Add
epaint::RoundedRectprimitive #8440 by @emilk - Add
BandShape#8476 by @emilk - Allow transforming after shapes were tessellated and rounded #8587 by @lucasmerlin
- Add
AtomLayoutStyle#8465 by @lucasmerlin - Add
AtomKind::Paint#8524 by @lucasmerlin - StyleProvider for TextEdit and DragValue #8455 by @lucasmerlin
- Add
WidgetText::concatfor joining differently styledRichTexts #8538 by @emilk - Add
RichText::color_overrideto read the explicit text color #8564 by @pederbe - Add
CollapsingHeader::customfor collapsing headers with a custom header UI #8549 by @Its-Just-Nans - Add
MenuConfig::submenu_gapto override the hardcoded gap between a menu and its submenus #8338 by @kiwirm - Allow explicit popup sizing passes #8407 by @yay
- Add
Context::root_uiandContext::run_pass#8535 by @emilk - Add
Context::set_repaint_observer#8644 by @syl20bnr - Add
Plugin::on_exit#8527 by @lucasmerlin - Add
Response::container_hovered,container_clicked,container_context_menu, etc #8537 by @emilk - Make
Areas::set_statepublic #8645 by @syl20bnr - IdTypeMap: add iterator iter_temp_by_type (analogous to remove_by_type) #8672 by @the-maddin
- Add
Keys specific to Windows & Mac keyboards #8373 by @ans1ble - Add
KeyboardShortcut::conflicts_with_text_editing#8536 by @emilk - Add
MouseWheelSourceandInputState::scroll_source()#8665 by @emilk - Add option
scroll_zoomsfor mouse wheel to zoom instead of scroll inside aScenecontainer #7891 by @Tristan117 - Add double-click-and-drag and triple-click-and-drag text selection #8370 by @mudbungie
- Support AccessKit
SetValueandReplaceSelectedTextinTextEdit#8701 by @Elitelord - Improve the fallback syntax highlighter in
egui_extras#8708 by @emilk
🔧 Changed
- Make
Context::add_glyph_rasterizeridempotent #8600 by @emilk - Apply
set_fonts/add_fontright away when no font is loaded yet, or no text has been laid out this pass #8602, #8609 by @emilk - Name a
Ui,Area,PopuporTooltipin the accessibility tree #8607 by @emilk - Fail kittest tests when an input widget has no accessible name (read-only text fields are exempt) #8589, #8611 by @emilk
- Clarify what
Idto pass inaccessibility_parent#8582 by @lucasmerlin - Bump accesskit{,_consumer,_winit} to latest versions #8496 by @alice
- Rename
Ui::idtoUi::scope_idand clarify its docstring #8542 by @emilk - Use
Ui::unique_idforWidgetRect::parent_id#8543 by @emilk - Build
ComboBoxfrom atoms, and takeimpl IntoAtoms#8618 by @emilk - Round the corners of the color picker #8439 by @emilk
- Deprecate
global_theme_preference_switchin favor ofglobal_theme_preference_buttons#8505 by @emilk - Feat: add more documentation on
Image::texture_options#8357 by @Its-Just-Nans - Support the X11/Wayland PRIMARY selection #8428 by @hallyhaa
- Make
DroppedFile::web_file(and itsweb-sysdependency) opt-in #8669 by @DouglasDwyer - Keep
egui::ContextSend + Syncwith wasm threads #8638 by @teolines - Enable
clippy::std_instead_of_allocin core egui crates #8702 by @emilk
🔥 Removed
- Remove the
Fontborrow-bag; put its methods onFontsImpl#8504 by @emilk - Remove the
AsIdtrait #8584 by @emilk
🐛 Fixed
- Fix changing widget IDs and false-positive ID change warnings across passes #8316 by @vlansco
- Warn again when automatic widget IDs shift between passes #8670 by @emilk
- Ensure nested
AtomLayouts have unique ids #8556 by @lucasmerlin - Remove unfocusable widgets from the widget cache #8653 by @ori-sky
- Fix AccessKit
ScrollIntoViewfor aUiwithUiBuilder::sense#8646 by @GavinPizza - Fix popups immediately closing on mouse button release #7624 by @vladbat00
- Show menu without a click if another menu is open #7802 by @mkeeter
- Respect the menu style config in sub menus #8572 by @lucasmerlin
- Paint
SubMenuButtonarrow as a triangle instead of a glyph #8525 by @lucasmerlin - Show tooltips of container responses when hovering their children #7909 by @optozorax
- Enable mouse wheel scrolling while dragging inside a
ScrollArea#7919 by @rustbasic - Fix #8495: Match scrollbar interaction rect to drawn bar rect (remove dead zone) #8635 by @dajiaohuang
- Fix scroll modifiers getting stuck when
TouchPhase::Endnever arrives #8636 by @SulimanAbdulrazzaq - Fix NaN panic in
Scenewith zeroscene_rectand unbounded zoom #8622 by @emilk - Fix: Panel/Scene clip rect should respect parent #8562 by @DouglasDwyer
- Fix : an issue where double-clicks were judged as triple-clicks #7915 by @rustbasic
- Fix
TextEditlayout shift with custom margin; unclippedTextEditgrows to fit text #8628 by @emilk - Fix: TextFormat::valign not applied correctly with custom line_height #8030 by @rustbasic
- Don't start a CJK row with full-width closing punctuation #8658 by @Zaneris
- Fix
DragValuereporting changes while typing withupdate_while_editing(false)#8627 by @SulimanAbdulrazzaq - Fix color picker RGB drift when editing alpha #8483 by @ishuowang
- Preserve drop-zone frame styling when idle #8633 by @pederbe
- Keep a
Window's position after a restart #8637 by @teolines - Fix burst of extra repaints before request_repaint_after deadlines #8595 by @xmakro
- Preserve safe area insets when appending input #8484 by @ishuowang
🚀 Performance
- Avoid cross-viewport GalleyCache eviction #8528 by @rustbasic
