egui: an immediate mode GUI in Rust that runs on the web and natively
egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native
At a glance
- What is it?
- egui is a pure-Rust immediate mode GUI library built around a simple per-frame redraw loop, with eframe as its official application framework. It is a good fit for tools, editors and game overlays, and a poor fit if you need native-looking widgets or a stable API surface.
- Who is it for?
- Adopt egui if you are writing a Rust tool, editor, debug overlay or game UI and you want the same code to run natively and in the browser through eframe. Do not adopt it if you need a native-looking interface, a frozen API, or a widget set that covers every desktop convention; the README states plainly that interfaces are still in flux and that new releases will have breaking changes.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What egui is for, and who it is actually aimed at
egui is a library, not a framework. The README states that directly: "egui is a library you call into, not an environment you program for." That single sentence explains most of the design decisions that follow. You do not register callbacks, you do not subclass a widget, and you do not hand the library a retained tree of objects to manage. On every frame you call into egui, describe the interface you want right now, and egui draws it.
The intended audience is narrower than "everyone who needs a GUI in Rust". The project's own goals list names the easiest-to-use GUI library, portability between web and native, and easy integration into any environment. Its non-goals are just as informative: egui does not try to be the most powerful GUI library, and it does not try to produce a native-looking interface. If your requirement is a settings dialog that looks like it was drawn by the operating system, egui is the wrong starting point and the README says so.
Where it fits instead is tooling. The README points at the Rerun Viewer as an example of a professional-looking application built on egui. Debug overlays, in-game editors, developer tools, and small web apps written in Rust are the natural home. The project also claims the title of "the simplest way to make a web app in Rust", which is a claim about effort, not about capability.
Why immediate mode changes how you write the UI
The README's example is the clearest statement of the mechanism. You write a closure that runs every frame, and inside it you call methods on a `Ui` value. Labels, sliders and buttons are function calls whose return values you read immediately, so there is no binding layer between your state and the widget. The widget does not own the value; your variable does, and you pass a mutable reference to it.
The consequence is that state lives in your struct, not in the widget tree. A slider is constructed from a range and a mutable reference, and when the user drags it, the value behind that reference changes. A button returns whether it was clicked this frame, and you act on that in the same block of code. Nothing is stored between frames except what you choose to store.
This is why the README says egui is "pure immediate mode: no callbacks". There is no event handler to register and no lifetime problem where a closure outlives the data it captures. The cost is that the whole interface description runs again on every frame, so anything expensive inside that closure runs at frame rate. The project targets 60 Hz in debug builds, which sets the budget you are working against.
Above the widgets sits `epaint`, described as a simple 2D graphics API for custom painting. That is the layer to reach for when the built-in widgets do not cover what you need, rather than trying to bend an existing widget into an unusual shape.
Installing egui and running your first window
egui is published on crates.io as `egui`, and the official application framework is `eframe`, which the README describes as supporting Web, Linux, Mac, Windows and Android. For a native application you depend on eframe, not on egui directly, because eframe supplies the window, the event loop and the renderer.
The README's quick start points at the `examples/` folder in the repository and at the eframe template repository for web apps. The smallest example in the tree is `examples/hello_world_simple`. Running the demo app locally is the fastest way to see what the library can do:
cargo run --release -p egui_demo_appOn Linux, the README notes that the native backend, `egui-wgpu`, needs system libraries before the demo will build. It gives this command for Debian-family distributions:
sudo apt-get install -y libclang-dev libgtk-3-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libssl-devThe README is explicit that this is only for the demo app and that egui itself is platform agnostic. Do not read the dependency list as a requirement of the library.
Inside your own application, the drawing code is the part shown in the README. A heading, a horizontal row with a label and a text field, a slider bound to an integer, and a button that mutates it:
ui.heading("My egui Application");
ui.horizontal(|ui| {
ui.label("Your name: ");
ui.text_edit_singleline(&mut name);
});
ui.add(egui::Slider::new(&mut age, 0..=120).text("age"));
if ui.button("Increment").clicked() {
age += 1;
}
ui.label(format!("Hello '{name}', age {age}"));What you should see is a heading, an editable name field, a slider labelled age, and a button that increments the age and updates the label below it. Note the shape of the button check: `clicked()` is read once, in the frame where the click happened, and the mutation happens immediately after.
Images work through the same call style, using a macro that embeds the file at compile time:
ui.image(egui::include_image!("ferris.png"));If you want to see the full widget set before writing anything, the README links a web demo that runs in any browser with Wasm and WebGL support, and the demo's source is linked from within it.
The API is not stable, and that is the main cost of adopting egui
The README states that egui "lacks many features and the interfaces are still in flux", and that new releases will have breaking changes. That is not a hedge buried in a footnote; it is in the State section, above the feature list. Anyone planning to build on egui should price in periodic migration work.
The release cadence backs this up. Version 0.36.0 arrived on 2026-08-05 with improved mobile keyboard support, 0.36.1 on 2026-08-07 with a `Sense::drag()` bugfix, and 0.36.2 on 2026-09-08 with a `TextEdit::event_filter` addition plus bugfixes. Patch releases carrying behavioural fixes are normal here. If you pin a version and stop reading the changelog, you will eventually be several breaking changes behind.
There is a second limitation worth stating plainly: the non-goal of a native-looking interface is a real constraint, not a stylistic preference. Widgets will not match the platform's own controls, and if your users expect a macOS or Windows appearance, egui will look like a foreign element in their desktop. The README does not offer a theming path that solves this, and it does not claim to.
Finally, egui is a library with a rendering contract underneath it. The README says it can be used anywhere you can draw textured triangles, which is what makes engine integration possible, but it also means that if you are not already in an environment that provides that, you are relying on eframe or on one of the integrations to supply it.
How egui differs from a retained-mode toolkit
The obvious comparison is with a retained-mode Rust toolkit such as GTK bindings or a Qt binding. In those systems you construct widgets once, keep handles to them, and mutate them in response to events. The widget tree is the source of truth for what is on screen, and your job is to keep it in sync with your data.
In egui the direction is reversed. Your data is the source of truth, and the interface is a function of it, recomputed each frame. There is no synchronisation problem because there is nothing to synchronise. There is also no widget identity to hold onto, which is why the README describes egui as extensible through writing your own widgets rather than through subclassing an existing hierarchy.
The practical difference shows up in two places. First, layout: a retained toolkit gives you a layout engine with constraints and a widget that remembers where it was; egui computes layout as part of the frame, which is why the README lists automatic wrapping and collapsing headers as features rather than as given. Second, integration: a retained toolkit wants to own your event loop, while egui expects to be called from whatever loop you already have, which is what makes the game-engine integrations possible.
If your application is a long-lived document editor with a complex, persistent widget tree, immediate mode will feel like you are rebuilding something the toolkit would have given you. If your application is a tool that draws a control panel over something else, immediate mode removes an entire category of bookkeeping.
Integrating egui into an existing engine or renderer
The repository is a Cargo workspace, and the crate layout tells you where the seams are. `crates/egui` is the library itself, `crates/epaint` is the 2D painting layer, `crates/emath` holds the math types, `crates/ecolor` the colour types, and `crates/epaint_default_fonts` the bundled fonts. On top of those sit the platform crates: `crates/egui-winit` for windowing and input, `crates/egui-wgpu` and `crates/egui_glow` for the two rendering backends.
The README names `egui-wgpu` as the native backend, built on the `wgpu` crate. That is the piece that turns egui's draw commands into actual GPU work, and it is the reason the Linux system packages are needed for the demo. `egui_glow` is the alternative backend for OpenGL, and the examples folder contains `examples/custom_3d_glow`, which is the reference for mixing your own 3D rendering with an egui overlay.
Because egui only needs textured triangles, integration into an engine means providing a texture and a triangle list, not adopting an application framework. The README states this as the reason egui can be dropped into a game engine of choice. The trade-off is that you own the input plumbing: `egui-winit` handles the common case, but an engine with its own input model will need to feed events into egui itself.
Two further crates are worth knowing about. `crates/egui_extras` holds widgets that are deliberately kept out of the core, and `crates/egui_kittest` is the testing harness. The README also points to a wiki page of third-party egui crates for widgets and features maintained by the community, which is where to look before writing your own.
Licence, dependencies and the cost of staying current
egui is dual-licensed under MIT OR Apache-2.0, matching the workspace's `license` field. Both licence files, `LICENSE-MIT` and `LICENSE-APACHE`, are at the repository root, and the README carries badges for both. That is the standard permissive pairing in the Rust ecosystem and it is the same choice made by much of the crates.io index, so it rarely raises questions in a commercial codebase. This is a description of the licence terms, not legal advice; if your organisation has specific obligations around attribution or patent clauses, the two files are short and worth reading directly.
The dependency story is deliberately small. The README states that egui has a minimal set of default dependencies and that heavier dependencies are kept out of egui even as opt-in, with all code in egui being Wasm-friendly. That matters for two reasons. It keeps compile times and binary size down, and it means the platform crates, not the core library, are where the heavy machinery lives. If you are not using eframe, you are not pulling in a windowing stack.
Upgrade cost is the recurring expense. The workspace pins `rust-version = "1.95"` and uses edition 2024, so a toolchain older than that will not build the workspace at all. Beyond the toolchain, the breaking-change policy described in the README means upgrades are not free, and the release history shows patch releases that fix behaviour rather than only adding features. The practical approach is to read `CHANGELOG.md` and `RELEASES.md` before bumping, and to treat the version number as informative rather than as a stability guarantee.
Editorial conclusion
Adopt egui if you are writing a Rust tool, editor, debug overlay or game UI and you want the same code to run natively and in the browser through eframe. Do not adopt it if you need a native-looking interface, a frozen API, or a widget set that covers every desktop convention; the README states plainly that interfaces are still in flux and that new releases will have breaking changes. Before committing, verify two things yourself: that your target platforms build with the workspace's rust-version of 1.95, and that the widgets you need exist either in egui or in the third-party crates wiki. If both hold, the per-frame model is the smallest amount of GUI code you will write in Rust.
Frequently asked questions
What is egui used for?
egui is a GUI library for Rust used to build application interfaces that run on the web and natively from the same code. The README points to the Rerun Viewer as an example of a professional-looking application built with it, and describes it as a library you call into rather than a framework you program for.
What does ImGui do?
The README does not discuss ImGui directly, but it does describe egui's model as pure immediate mode with no callbacks, which is the defining characteristic of that family of libraries. In this model you describe the whole interface again on every frame instead of building a persistent widget tree.
Is egui immediate mode?
Yes. The README lists "Pure immediate mode: no callbacks" among the project's goals, and the example shows widgets being constructed each frame from mutable references to your own variables.
Can egui be used with Rust?
egui is written in pure Rust and published on crates.io, with the workspace requiring rust-version 1.95 and edition 2024. The official application framework, eframe, supports Web, Linux, Mac, Windows and Android.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/emilk-egui)
Community notes