https://github.com/emilk/egui Skip to content Sign up * Why GitHub? Features - + Mobile - + Actions - + Codespaces - + Packages - + Security - + Code review - + Issues - + Integrations - + GitHub Sponsors - + Customer stories- * Team * Enterprise * Explore + Explore GitHub - Learn and contribute + Topics - + Collections - + Trending - + Learning Lab - + Open source guides - Connect with others + The ReadME Project - + Events - + Community forum - + GitHub Education - + GitHub Stars program - * Marketplace * Pricing Plans - + Compare plans - + Contact Sales - + Education - [ ] * # In this repository All GitHub | Jump to | * No suggested jump to results * # In this repository All GitHub | Jump to | * # In this user All GitHub | Jump to | * # In this repository All GitHub | Jump to | Sign in Sign up {{ message }} emilk / egui * Notifications * Star 4k * Fork 197 egui: an easy-to-use immediate mode GUI in pure Rust View license 4k stars 197 forks Star Notifications * Code * Issues 83 * Pull requests 24 * Discussions * Actions * Wiki * Security * Insights More * Code * Issues * Pull requests * Discussions * Actions * Wiki * Security * Insights master Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags 12 branches 8 tags Code * Clone HTTPS GitHub CLI [https://github.com/e] Use Git or checkout with SVN using the web URL. [gh repo clone emilk/] Work fast with our official CLI. Learn more. * Open with GitHub Desktop * Download ZIP Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Go back Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Go back Launching Xcode If nothing happens, download Xcode and try again. Go back Launching Visual Studio Code Your codespace will open once ready. There was a problem preparing your codespace, please try again. Latest commit @emilk emilk Improve error message on bad texture allocation ... 784bac5 Jul 29, 2021 Improve error message on bad texture allocation Fixes #592 784bac5 Git stats * 1,417 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .github Add libxkbcommon-dev to list of linux deps (#549) Jul 6, 2021 docs Release 0.13.0 - Better panels, plots and new visual style Jun 24, 2021 eframe Improve README files for all crates Jul 29, 2021 egui Pass more inner return values (#557) Jul 21, 2021 egui_demo_app Release 0.13.0 - Better panels, plots and new visual style Jun 24, 2021 egui_demo_lib Plot: Line styles (#482) Jul 6, 2021 egui_glium Improve error message on bad texture allocation Jul 29, 2021 egui_web Improve error message on bad texture allocation Jul 29, 2021 emath Add Vec2::to_pos2 Jul 20, 2021 epaint Plot: Line styles (#482) Jul 6, 2021 epi Improve README files for all crates Jul 29, 2021 media Release 0.13.0 - Better panels, plots and new visual style Jun 24, 2021 sh Enable a bunch more clippy lints May 9, 2021 .gitignore Combine demo_glium and demo_web into one egui_demo crate Dec 19, 2020 ARCHITECTURE.md Use ab_glyph instead of rusttype for font rendering (#490) Jun 24, 2021 CHANGELOG.md Pass more inner return values (#557) Jul 21, 2021 CONTRIBUTING.md Move shell scripts into sh/ subfolder May 9, 2021 Cargo.lock Release egui 0.13.1: Plot fixes Jun 28, 2021 Cargo.toml faster debug builds on mac Apr 18, 2021 LICENSE-APACHE [license] licence under MIT or Apache-2.0 May 26, 2020 LICENSE-MIT Add years and email in LICENSE-MIT Mar 21, 2021 README.md readme: add egui_glfw_gl (#586) Jul 29, 2021 rust-toolchain Use old 1.51 toolchain instead of bleeding edge (#505) Jun 23, 2021 View code [ ] egui: an easy-to-use GUI in pure Rust Quick start Demo Example Goals Non-goals Who is egui for? egui vs Dear ImGui State Features How it works Integrations Official 3rd party Writing your own egui integration Debugging your integration Things look jagged My text is blurry My windows are too transparent or too dark Why immediate mode Advantages of immediate mode Usability Disadvantages of immediate mode Layout CPU usage IDs FAQ Can I use egui with non-latin characters? Can I customize the look of egui? What about accessibility, such as screen readers? What is the difference between egui and eframe? Why is egui_web using so much CPU in Firefox? Why does my web app not fill the full width of the screen? Other Conventions and design choices Inspiration Name Credits / Licenses README.md egui: an easy-to-use GUI in pure Rust Latest version Documentation unsafe forbidden Build Status MIT Apache egui is a simple, fast, and highly portable immediate mode GUI library for Rust. egui runs on the web, natively, and in your favorite game engine (or will soon). egui aims to be the easiest-to-use Rust GUI library, and the simplest way to make a web app in Rust. egui can be used anywhere you can draw textured triangles, which means you can easily integrate it into your game engine of choice. Sections: * Quick start * Demo * Goals * Who is egui for? * State / features * How it works * Integrations * Why immediate mode * FAQ * Other Quick start If you just want to write a GUI application in Rust (for the web or for native), go to https://github.com/emilk/egui_template/ and follow the instructions there! If you want to integrate egui into an existing engine, go to the Integrations section. If you have questions, use Discussions. If you want to contribute to egui, please read the Contributing Guidelines Demo Click to run egui web demo (works in any browser with WASM and WebGL support). To test the demo app locally, run cargo run --release -p egui_demo_app. The native backend is currently using glium (though there are plans to change that) and should work out-of-the-box on Mac and Windows, but on Linux you need to first run: sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libspeechd-dev libxkbcommon-dev On Fedora Rawhide you need to run dnf install clang clang-devel clang-tools-extra speech-dispatcher-devel NOTE: This is just for the demo app - egui itself is completely platform agnostic! Example 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("Click each year").clicked() { age += 1; } ui.label(format!("Hello '{}', age {}", name, age)); [demo] Goals * The easiest to use GUI library * Responsive: target 60 Hz in debug build * Friendly: difficult to make mistakes, and shouldn't panic * Portable: the same code works on the web and as a native app * Easy to integrate into any environment * A simple 2D graphics API for custom painting (epaint). * No callbacks * Pure immediate mode * Extensible: easy to write your own widgets for egui * Modular: You should be able to use small parts of egui and combine them in new ways * Safe: there is no unsafe code in egui * Minimal dependencies: ahash atomic_refcell ordered-float ab_glyph . egui is not a framework. egui is a library you call into, not an environment you program for. NOTE: egui does not claim to have reached all these goals yet! egui is still work in progress. Non-goals * Become the most powerful GUI library * Native looking interface * Advanced and flexible layouts (that's fundamentally incompatible with immediate mode) Who is egui for? egui aims to be the best choice when you want a simple way to create a GUI, or you want to add a GUI to a game engine. If you are not using Rust, egui is not for you. If you want a GUI that looks native, egui is not for you. If you want something that doesn't break when you upgrade it, egui isn't for you (yet). But if you are writing something interactive in Rust that needs a simple GUI, egui may be for you. egui vs Dear ImGui The obvious alternative to egui is imgui-rs, the Rust wrapper around the C++ library Dear ImGui. Dear ImGui is a great library, which a lot more features and polish compared to egui. However, egui provides some benefits for Rust users: * egui is pure Rust * egui is easily compiled to WASM * egui lets you use native Rust String types (imgui-rs forces you to use annoying macros and wrappers for zero-terminated strings) * Writing your own widgets in egui is simple egui also tries to improve your experience in other small ways: * Windows are automatically sized based on their contents * Windows are automatically positioned to not overlap with each other * Some subtle animations make egui come alive So in summary: * egui: pure Rust, new, exciting, work in progress * Dear ImGui: feature rich, well tested, cumbersome Rust integration State egui is in active development. It works well for what it does, but it lacks many features and the interfaces are still in flux. New releases will have breaking changes. Features * Widgets: label, text button, hyperlink, checkbox, radio button, slider, draggable value, text editing, combo box, color picker * Layouts: horizontal, vertical, columns, automatic wrapping * Text editing: multiline, copy/paste, undo, emoji supports * Windows: move, resize, name, minimize and close. Automatically sized and positioned. * Regions: resizing, vertical scrolling, collapsing headers (sections) * Rendering: Anti-aliased rendering of lines, circles, text and convex polygons. * Tooltips on hover * More [widget_gallery] Light Theme: [light_theme] How it works Loop: * Gather input (mouse, touches, keyboard, screen size, etc) and give it to egui * Run application code (Immediate Mode GUI) * Tell egui to tessellate the frame graphics to a triangle mesh * Render the triangle mesh with your favorite graphics API (see OpenGL example) or use eframe, the egui framework crate. Integrations egui is build to be easy to integrate into any existing game engine or platform you are working on. egui itself doesn't know or care on what OS it is running or how to render things to the screen - that is the job of the egui integration. The integration needs to do two things: * IO: Supply egui with input (mouse position, keyboard presses, ...) and handle egui output (cursor changes, copy-paste integration, ...). * Painting: Render the textured triangles that egui outputs. Official I maintain two official egui integrations made for apps: * egui_web for making a web app. Compiles to WASM, renders with WebGL. Click to run the egui demo. * egui_glium for compiling native apps with Glium. If you making an app, consider using eframe, a framework which allows you to write code that works on both the web (egui_web) and native (using egui_glium). 3rd party * bevy_egui for the Bevy game engine. * egui_glfw_gl for GLFW. * egui-miniquad for Miniquad. * egui-macroquad for macroquad. * egui_sdl2_gl for SDL2. * egui_vulkano for Vulkano. * egui_winit_ash_vk_mem for for winit, ash and vk_mem. * egui_winit_platform for winit (requires separate painter). * egui_winit_vulkano for Vulkano. * ggez-egui for the ggez game framework. * godot-egui for godot-rust. * nannou_egui for nannou. * egui-tetra for Tetra, a 2D game framework. * egui_wgpu_backend for wgpu (WebGPU API). Missing an integration for the thing you're working on? Create one, it is easy! Writing your own egui integration You need to collect egui::RawInput, paint egui::ClippedMesh:es and handle egui::Output. The basic structure is this: let mut egui_ctx = egui::Context::new(); // Game loop: loop { let raw_input: egui::RawInput = my_integration.gather_input(); egui_ctx.begin_frame(raw_input); my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here let (output, shapes) = egui_ctx.end_frame(); let clipped_meshes = egui_ctx.tessellate(shapes); // create triangles to paint my_integration.paint(clipped_meshes); my_integration.set_cursor_icon(output.cursor_icon); // Also see `egui::Output` for more } For a reference OpenGL backend, see the egui_glium painter or the egui_web WebGL painter. Debugging your integration Things look jagged * Turn off backface culling. My text is blurry * Make sure you set the proper pixels_per_point in the input to egui. * Make sure the texture sampler is not off by half a pixel. Try nearest-neighbor sampler to check. My windows are too transparent or too dark * egui uses premultiplied alpha, so make sure your blending function is (ONE, ONE_MINUS_SRC_ALPHA). * Make sure your texture sampler is clamped (GL_CLAMP_TO_EDGE). * Use an sRGBA-aware texture if available (e.g. GL_SRGB8_ALPHA8). + Otherwise: remember to decode gamma in the fragment shader. * Decode the gamma of the incoming vertex colors in your vertex shader. * Turn on sRGBA/linear framebuffer if available (GL_FRAMEBUFFER_SRGB). + Otherwise: gamma-encode the colors before you write them again. Why immediate mode egui is an immediate mode GUI library, as opposed to a retained mode GUI library. The difference between retained mode and immediate mode is best illustrated with the example of a button: In a retained GUI you create a button, add it to some UI and install some on-click handler (callback). The button is retained in the UI, and to change the text on it you need to store some sort of reference to it. By contrast, in immediate mode you show the button and interact with it immediately, and you do so every frame (e.g. 60 times per second). This means there is no need for any on-click handler, nor to store any reference to it. In egui this looks like this: if ui.button("Save file").clicked() { save(file); }. There are advantages and disadvantages to both systems. The short of it is this: immediate mode GUI libraries are easier to use, but less powerful. Advantages of immediate mode Usability The main advantage of immediate mode is that the application code becomes vastly simpler: * You never need to have any on-click handlers and callbacks that disrupts your code flow. * You don't have to worry about a lingering callback calling something that is gone. * Your GUI code can easily live in a simple function (no need for an object just for the UI). * You don't have to worry about app state and GUI state being out-of-sync (i.e. the GUI showing something outdated), because the GUI isn't storing any state - it is showing the latest state immediately. In other words, a whole lot of code, complexity and bugs are gone, and you can focus your time on something more interesting than writing GUI code. Disadvantages of immediate mode Layout The main disadvantage of immediate mode is it makes layout more difficult. Say you want to show a small dialog window in the center of the screen. To position the window correctly the GUI library must first know the size of it. To know the size of the window the GUI library must first layout the contents of the window. In retained mode this is easy: the GUI library does the window layout, positions the window, then checks for interaction ("was the OK button clicked? "). In immediate mode you run into a paradox: to know the size of the window, we must do the layout, but the layout code also checks for interaction ("was the OK button clicked?") and so it needs to know the window position before showing the window contents. This means we must decide where to show the window before we know its size! This is a fundamental shortcoming of immediate mode GUIs, and any attempt to resolve it comes with its own downsides. One workaround is to store the size and use it the next frame. This produces a frame-delay for the correct layout, producing occasional flickering the first frame something shows up. egui does this for some things such as windows and grid layouts. You can also call the layout code twice (once to get the size, once to do the interaction), but that is not only more expensive, it's also complex to implement, and in some cases twice is not enough. egui never does this. For "atomic" widgets (e.g. a button) egui knows the size before showing it, so centering buttons, labels etc is possible in egui without any special workarounds. CPU usage Since an immediate mode GUI does a full layout each frame, the layout code needs to be quick. If you have a very complex GUI this can tax the CPU. In particular, having a very large UI in a scroll area (with very long scrollback) can be slow, as the content needs to be layed out each frame. If you design the GUI with this in mind and refrain from huge scroll areas (or only lay out the part that is in view) then the performance hit is generally pretty small. For most cases you can expect egui to take up 1-2 ms per frame, but egui still has a lot of room for optimization (it's not something I've focused on yet). You can also set up egui to only repaint when there is interaction (e.g. mouse movement). If your GUI is highly interactive, then immediate mode may actually be more performant compared to retained mode. Go to any web page and resize the browser window, and you'll notice that the browser is very slow to do the layout and eats a lot of CPU doing it. Resize a window in egui by contrast, and you'll get smooth 60 FPS at no extra CPU cost. IDs There are some GUI state that you want the GUI library to retain, even in an immediate mode library such as egui. This includes position and sizes of windows and how far the user has scrolled in some UI. In these cases you need to provide egui with a seed of a unique identifier (unique within the parent UI). For instance: by default egui uses the window titles as unique IDs to store window positions. If you want two windows with the same name (or one window with a dynamic name) you must provide some other ID source to egui (some unique integer or string). egui also needs to track which widget is being interacted with (e.g. which slider is being dragged). egui uses unique id:s for this awell, but in this case the IDs are automatically generated, so there is no need for the user to worry about it. In particular, having two buttons with the same name is no problem (this is in contrast with Dear ImGui). Overall, ID handling is a rare inconvenience, and not a big disadvantage. FAQ Also see GitHub Discussions. Can I use egui with non-latin characters? Yes! But you need to install your own font (.ttf or .otf) using Context::set_fonts. Can I customize the look of egui? Yes! You can customize the colors, spacing and sizes of everything. By default egui comes with a dark and a light theme. What about accessibility, such as screen readers? There is experimental support for a screen reader. In the web demo you can enable it in the "Backend" tab. Read more at https://github.com/emilk/egui/issues/167. What is the difference between egui and eframe? egui is a 2D user interface library for laying out and interacting with buttons, sliders, etc. egui has no idea if it is running on the web or natively, and does not know how to collect input or show things on screen. That is the job of the integration or backend. It is common to use egui from a game engine (using e.g. bevy_egui), but you can also use egui stand-alone using eframe. eframe has integration for web and native, and handles input and rendering. The frame in eframe stands both for the frame in which your egui app resides and also for "framework" (frame is a framework, egui is a library). Why is egui_web using so much CPU in Firefox? On Linux and Mac, Firefox will copy the WebGL render target from GPU, to CPU and then back again: https://bugzilla.mozilla.org/ show_bug.cgi?id=1010527#c0 Why does my web app not fill the full width of the screen? To alleviate the above mentioned performance issues the default max-width of an egui web app is 1024 points. You can change this by ovveriding the fn max_size_points of epi::App. Other Conventions and design choices All coordinates are in screen space coordinates, with (0, 0) in the top left corner All coordinates are in "points" which may consist of many physical pixels. All colors have premultiplied alpha. egui uses the builder pattern for construction widgets. For instance: ui.add(Label::new("Hello").text_color(RED)); I am not a big fan of the builder pattern (it is quite verbose both in implementation and in use) but until Rust has named, default arguments it is the best we can do. To alleviate some of the verbosity there are common-case helper functions, like ui.label("Hello");. Instead of using matching begin/end style function calls (which can be error prone) egui prefers to use FnOnce closures passed to a wrapping function. Lambdas are a bit ugly though, so I'd like to find a nicer solution to this. Inspiration The one and only Dear ImGui is a great Immediate Mode GUI for C++ which works with many backends. That library revolutionized how I think about GUI code and turned GUI programming from something I hated to do to something I now enjoy. Name The name of the library and the project is "egui" and pronounced as "e-gooey". Please don't write it as "EGUI". The library was originally called "Emigui", but was renamed to "egui" in 2020. Credits / Licenses egui author: Emil Ernerfeldt egui is under MIT OR Apache-2.0 license. Fonts: * emoji-icon-font.ttf: Copyright (c) 2014 John Slegers , MIT License * NotoEmoji-Regular.ttf: google.com/get/noto, SIL Open Font License * ProggyClean.ttf: Copyright (c) 2004, 2005 Tristan Grimmer. MIT License. http://www.proggyfonts.net/ * Ubuntu-Light.ttf by Dalton Maag: Ubuntu font licence About egui: an easy-to-use immediate mode GUI in pure Rust Topics rust gui game-development Resources Readme License View license Contributors 56 * @emilk * @EmbersArc * @optozorax * @parasyte * @lucaspoffo * @follower * @n2 * @phoglund * @quadruple-output * @TheCallSign * @DrOptix + 45 contributors Languages * Rust 98.7% * Other 1.3% * (c) 2021 GitHub, Inc. * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.