Skip to content

Releases: emilk/egui

0.34.1: Enable WebGL fallback in eframe

27 Mar 10:29

Choose a tag to compare



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.

eframe 0.34.1 changelog

0.34.0: More `Ui`, less `Context`

26 Mar 11:18

Choose a tag to compare



(yes, we have a logo now!)

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.

egui 0.34.0 changelog

Highlights from this release

  • Sharper text unlocked by switching font rendering crate to skrifa
  • Fade out edges of ScrollAreas
  • Use Ui as the main entrypoint

Skrifa and font hinting

The font rendering backend was switched from ab_glyph to skrifa + vello_cpu. This enabled us support
font hinting and variations. It also paves the way for more font improvements in the future, like support for color
emojis and adding helpers for variations like RichText::bold.

Font hinting makes text more clear (look at the =):

Screen.Recording.2026-03-26.at.10.49.43.mov

We now support setting variable font parameters:

Screen.Recording.2026-03-26.at.11.37.21.mp4

(Unfortunately there is currently a bug with variations, meaning changing them live like this won't work in practise.
There is a draft PR to fix it, but it didn't make the release)

More Ui, less Context

egui has long had a confusing overlap in responsibilities between Context and Ui.
In particular, you could add panels to either one (or both!).
In this release, we switch from having Context be the main entrypoint, and instead provide whole-app Ui.
In egui we've replaced Context::run with Context::run_ui, and changed viewports to be given a &mut Ui instead of Context.
In eframe we've deprecated App::update replaced it with App::ui (which provides a &mut Ui instead of a &Context).

In addition to this, Ui now derefs to Context, so all code like ui.ctx().input(…) can now be written ui.input(…).
This means you are much less likely to have to use naked Contexts.
Context can still be useful though, since they implement Clone and can be sent to other threads so you can call .request_repaint on them.

  • Add Context::run_ui #7736 by @emilk
  • Add Deref<Target = Context> for Ui #7770 by @emilk
  • Replace App::update with fn logic and fn ui #7775 by @emilk
  • Rename Context::style to global_style; avoid confusion w/ Ui::style #7772 by @emilk
  • Rename functions in Context to avoid confusion #7773 by @emilk
  • Viewports: give the caller a Ui instead of Context #7779 by @emilk

Changed panel API

As part of the above work, we have unified the panel API.
SidePanel and TopBottomPanel are deprecated, replaced by a single Panel.
Furthermore, it is now deprecated to use panels directly on Context. Use the show_inside functions instead, acting on Uis.

This unification and simplification will make it easier to maintain and improve panels going forward.

  • Add Panel to replace SidePanel and TopBottomPanel #5659 by @sharky98
  • Deprecate using Panel directly on a Context #7781 by @emilk
  • Deprecate CentralPanel::show #7783 by @emilk
  • Deprecate Context::used_size and Context::available_rect #7788 by @emilk

⭐ Added

🔧 Changed

  • Remove accesskit feature and always depend on accesskit #7701 by @emilk
  • Update MSRV from 1.88 to 1.92 #7793 by @JasperBRiedel
  • Improve modifier handling when scrolling #7678 by @emilk
  • Apply preferred font weight when loading variable fonts #7790 by @pmnxis
  • Make scroll bars and resize splitters visible to accesskit #7804 by @emilk
  • Allow moving existing widgets to the top of interaction stack #7805 by @emilk
  • Slightly change interact behavior around thin splitters #7806 by @emilk
  • Move window resize interaction to be over contents #7807 by @emilk
  • Don't expand widgets on hover #7808 by @emilk
  • Make FrameCache::get return a reference instead of cloning the cached value #7834 by @KonaeAkira
  • Update selected dependencies #7920 by @oscargus
  • Make Galley::pos_from_layout_cursor pub #7864 by @dionb
  • Update accesskit to 0.24.0 (and related deps) #7850 by @delan
  • Quit on Ctrl-Q #7985 by @emilk
  • Fade out the edges of ScrollAreas #8018 by @emilk

🔥 Removed

🐛 Fixed

  • Fix: ensure CentralPanel::show_inside allocates space in parent #7778 by @emilk
  • Heed constrain rect when auto-positioning windows #7786 by @emilk
  • Fix jitter when hovering edge of scroll area close to resize splitter #7803 by @emilk
  • Don't focus Areas, Windows and ScrollAreas #7827 by @lucasmerlin
  • Fix backspacing leaving last character in IME prediction not removed on macOS native and Safari #7810 by @umajho
    *...
Read more

0.33.3 - Improve kittest and text selection

11 Dec 14:42

Choose a tag to compare

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.

egui

  • Treat . as a word-splitter in text navigation #7741 by @emilk
  • Change text color of selected text #7691 by @emilk

egui_kittest changelog

egui_extras changelog

0.33.2

13 Nov 14:34

Choose a tag to compare

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.

egui changelog

⭐ Added

  • Add Plugin::on_widget_under_pointer to support widget inspector #7652 by @juancampa
  • Add Response::total_drag_delta and PointerState::total_drag_delta #7708 by @emilk

🔧 Changed

🐛 Fixed

  • Fix profiling::scope compile error when profiling using tracing backend #7646 by @PPakalns
  • Fix edge cases in "smart aiming" in sliders #7680 by @emilk
  • Hide scroll bars when dragging other things #7689 by @emilk
  • Prevent widgets sometimes appearing to move relative to each other #7710 by @emilk
  • Fix ui.response().interact(Sense::click()) being flakey #7713 by @lucasmerlin

eframe changelog

  • Fix jittering during window resize on MacOS for WGPU/Metal #7641 by @aspcartman
  • Make sure native_pixels_per_point is set during app creation #7683 by @emilk

0.33.0 - `egui::Plugin`, better kerning, kitdiff viewer

09 Oct 17:15

Choose a tag to compare

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.

egui 0.33.0 changelog

Highlights from this release:

  • egui::Plugin a improved way to create and access egui plugins
  • kitdiff, a viewer for egui_kittest image snapshots (and a general image diff tool)
  • better kerning

Improved kerning

As a step towards using parley for font rendering, @valadaptive has refactored the font loading and rendering code. A result of this (next to the font rendering code being much nicer now) is improved kerning.
Notice how the c moved away from the k:

Oct-09-2025 16-21-58

egui::Plugin trait

We've added a new trait-based plugin api, meant to replace Context::on_begin_pass and Context::on_end_pass.
This makes it a lot easier to handle state in your plugins. Instead of having to write to egui memory it can live right on your plugin struct.
The trait based api also makes easier to add new hooks that plugins can use. In addition to on_begin_pass and on_end_pass, the Plugin trait now has a input_hook and output_hook which you can use to inspect / modify the RawInput / FullOutput.

kitdiff, a image diff viewer

At rerun we have a ton of snapshots. Some PRs will change most of them (e.g. the one that updated egui and introduced the kerning improvements, ~500 snapshots changed!).
If you really want to look at every changed snapshot it better be as efficient as possible, and the experience on github, fiddeling with the sliders, is kind of frustrating.
In order to fix this, we've made kitdiff.
You can use it locally via

To install kitdiff run cargo install --git https://github.com/rerun-io/kitdiff. You might need to login with your github account for viewing artifacts and to prevent running into rate limits.

Here is a video showing the kerning changes in kitdiff (try it yourself):

Screen.Recording.2025-10-09.at.13.43.19.mp4

Migration guide

  • egui::Mutex now has a timeout as a simple deadlock detection
    • If you use a egui::Mutex in some place where it's held for longer than a single frame, you should switch to the std mutex or parking_lot instead (egui mutexes are wrappers around parking lot)
  • screen_rect is deprecated
    • In order to support safe areas, egui now has viewport_rect and content_rect.
    • Update all usages of screen_rect to content_rect, unless you are sure that you want to draw outside the safe area (which would mean your Ui may be covered by notches, system ui, etc.)

⭐ Added

🔧 Changed

🔥 Removed

🐛 Fixed

0.32.3 - Fix tooltips for ellided text

12 Sep 06:27

Choose a tag to compare

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.

egui

egui_extras

  • Fix deadlock in FileLoader and EhttpLoader #7515 by @emilk

0.32.2 - Ui::place, Harness::mask and more bug fixes

04 Sep 13:22

Choose a tag to compare

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.

Add Ui::place

Ui::place is similar to Ui::put, but it doesn't update the current Uis cursor. This is very useful when using the new Atoms or making badge-like widgets.
The following breaks with Ui::put but works just fine with Ui::place:

Screenshot 2025-07-14 at 10 58 30 Screenshot 2025-07-14 at 10 58 51

Add Harness::mask

Harness::mask allows for simple masking of Rects you don't want to be visible in snapshot test images. The rect will be masked with a ugly color to make it obvious whats going on:

image

egui

  • Add Ui::place, to place widgets without changing the cursor #7359 by @lucasmerlin
  • Fix: SubMenu should not display when ui is disabled #7428 by @ozwaldorf
  • Remove line breaks when pasting into single line TextEdit #7441 by @YgorSouza
  • Panic mutexes that can't lock for 30 seconds, in debug builds #7468 by @emilk
  • Fix: prevent calendar popup from closing on dropdown change #7409 by @AStrizh

egui_extras

egui_kittest

epaint

  • Panic mutexes that can't lock for 30 seconds, in debug builds #7468 by @emilk
  • Skip zero-length layout job sections #7430 by @HactarCE

Unsorted commits

  • Add track_caller to Mutex and RwLock for deadlock_detection b17d716

0.32.1 - Misc bug fixes

15 Aug 11:45

Choose a tag to compare

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.

egui changelog

⭐ Added

🐛 Fixed

eframe changelog

  • Enable wgpu default features in eframe / egui_wgpu default features #7344 by @lucasmerlin
  • Request a redraw when the url change through the popstate event listener #7403 by @irevoire

egui_kittest changelog

  • Fix UPDATE_SNAPSHOTS: only update if we didn't pass the test #7455 by @emilk

0.32.0 - Atoms, popups, and better SVG support

10 Jul 15:04
fabd4aa

Choose a tag to compare

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.

egui 0.32.0 changelog

This is a big egui release, with several exciting new features!

  • Atoms are new layout primitives in egui, for text and images
  • Popups, tooltips and menus have undergone a complete rewrite
  • Much improved SVG support
  • Crisper graphics (especially text!)

Let's dive in!

⚛️ Atoms

egui::Atom is the new, indivisible building block of egui (hence the name).
It lets you mix images and text in many places where you would previously only be able to add text.

Atoms is the first step towards a more powerful layout engine in egui - more to come!

Right now an Atom is an enum that can be either WidgetText, Image, or Custom.

The new AtomLayout can be used within widgets to do basic layout.
The initial implementation is as minimal as possible, doing just enough to implement what Button could do before.
There is a new IntoAtoms trait that works with tuples of Atoms. Each atom can be customized with the AtomExt trait
which works on everything that implements Into<Atom>, so e.g. RichText or Image.
So to create a Button with text and image you can now do:

let image = include_image!("my_icon.png").atom_size(Vec2::splat(12.0));
ui.button((image, "Click me!"));

Anywhere you see impl IntoAtoms you can add any number of images and text, in any order.

As of 0.32, we have ported the Button, Checkbox, RadioButton to use atoms
(meaning they support adding Atoms and are built on top of AtomLayout).
The Button implementation is not only more powerful now, but also much simpler, removing ~130 lines of layout math.

In combination with ui.read_response, custom widgets are really simple now, here is a minimal button implementation:

pub struct ALButton<'a> {
    al: AtomLayout<'a>,
}

impl<'a> ALButton<'a> {
    pub fn new(content: impl IntoAtoms<'a>) -> Self {
        Self {
            al: AtomLayout::new(content.into_atoms()).sense(Sense::click()),
        }
    }
}

impl<'a> Widget for ALButton<'a> {
    fn ui(mut self, ui: &mut Ui) -> Response {
        let Self { al } = self;
        let response = ui.ctx().read_response(ui.next_auto_id());

        let visuals = response.map_or(&ui.style().visuals.widgets.inactive, |response| {
            ui.style().interact(&response)
        });

        let al = al.frame(
            Frame::new()
                .inner_margin(ui.style().spacing.button_padding)
                .fill(visuals.bg_fill)
                .stroke(visuals.bg_stroke)
                .corner_radius(visuals.corner_radius),
        );

        al.show(ui).response
    }
}

You can even use Atom::custom to add custom content to Widgets. Here is a button in a button:

Screen.Recording.2025-07-10.at.13.10.52.mov
let custom_button_id = Id::new("custom_button");
let response = Button::new((
    Atom::custom(custom_button_id, Vec2::splat(18.0)),
    "Look at my mini button!",
))
.atom_ui(ui);
if let Some(rect) = response.rect(custom_button_id) {
    ui.put(rect, Button::new("🔎").frame_when_inactive(false));
}

Currently, you need to use atom_ui to get a AtomResponse which will have the Rect to use, but in the future
this could be streamlined, e.g. by adding a AtomKind::Callback or by passing the Rects back with egui::Response.

Basing our widgets on AtomLayout also allowed us to improve Response::intrinsic_size, which will now report the
correct size even if widgets are truncated. intrinsic_size is the size that a non-wrapped, non-truncated,
non-justified version of the widget would have, and can be useful in advanced layout
calculations like egui_flex.

Details

❕ Improved popups, tooltips, and menus

Introduces a new egui::Popup api. Checkout the new demo on https://egui.rs:

Screen.Recording.2025-07-10.at.11.47.22.mov

We introduced a new RectAlign helper to align a rect relative to an other rect. The Popup will by default try to find the best RectAlign based on the source widgets position (previously submenus would annoyingly overlap if at the edge of the window):

Screen.Recording.2025-07-10.at.11.36.29.mov

Tooltip and menu have been rewritten based on the new Popup api. They are now compatible with each other, meaning you can just show a ui.menu_button() in any Popup to get a sub menu. There are now customizable MenuButton and SubMenuButton structs, to help with customizing your menu buttons. This means menus now also support PopupCloseBehavior so you can remove your close_menu calls from your click handlers!

The old tooltip and popup apis have been ported to the new api so there should be very little breaking changes. The old menu is still around but deprecated. ui.menu_button etc now open the new menu, if you can't update to the new one immediately you can use the old buttons from the deprecated egui::menu menu.

We also introduced ui.close() which closes the nearest container. So you can now conveniently close Windows, Collapsibles, Modals and Popups from within. To use this for your own containers, call UiBuilder::closable and then check for closing within that ui via ui.should_close().

Details

▲ Improved SVG support

You can render SVG in egui with

ui.add(egui::Image::new(egui::include_image!("icon.svg"));

(Requires the use of egui_extras, with the svg feature enabled and a call to install_image_loaders).

Previously this would sometimes result in a blurry SVG, epecially if the Image was set to be dynamically scale based on the size of the Ui that contained it. Now SVG:s are always pixel-perfect, for truly scalable graphics.

svg-scaling

Details

✨ Crisper graphics

Non-SVG icons are also rendered better, and text sharpness has been improved, especially in light mode.

image

Details
  • Improve text sharpness #5838 by @emilk
  • Improve text rendering in light mode #7290 by @emilk
  • Improve texture filtering by doing it in gamma space #7311 by @emilk
  • Make text underline and strikethrough pixel perfect crisp #5857 by @emilk

Migration guide

We have some silently breaking changes (code compiles fine but behavior changed) that require special care:

wgpu backend features

  • wgpu 25 made the gles and vulkan backends optional
    • We missed this, so for now you need to manually opt in to those backends. Add the following to you Cargo.toml
      wgpu = "25" # enables the wgpu default features so we get the default backends
      

Menus close on click by default

  • Previously menus would only close on click outside
  • Either
    • Remove the ui.close_menu() calls from button click handlers sinc...
Read more

0.31.1 - TextEdit and egui_kittest fixes

05 Mar 07:46

Choose a tag to compare

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.

egui

egui_extras

egui_kittest

epaint

  • Fix panic when rendering thin textured rectangles #5692 by @PPakalns