Casey Muratori
Eliminating redundant widget state and evaluating controls procedurally each frame removes callback synchronization boilerplate while restoring unified application control flow.
AI-assisted summary of Immediate-Mode Graphical User Interfaces - 2005 — original source. Check the original for full context.
Source published:
Key ideas
- Casey Muratori formalizes Immediate-Mode Graphical User Interfaces (IMGUI), an alternative UI paradigm developed around 2002 that dispenses with retained widget hierarchies, initialization routines, and event-dispatch callbacks in favor of procedural per-frame execution. (0:01)
- The entire interaction model of an IMGUI system is governed by a global UIContext tracking just two states—'hot' (hovered/about to be interacted with) and 'active' (currently engaged)—eliminating redundant state cached across inactive widgets. (12:02)
- IMGUI mirrors modern graphics pipelines by treating UI as an imperative draw stream, allowing seamless embedding inside 3D rendering loops and dynamic animation transforms without scene-graph synchronization. (20:43)
- Key engineering trade-offs include a potential one-frame latency for global layout calculations in languages like C/C++ lacking introspection, as well as shifting coarse-grained culling responsibilities onto application code. (32:46)
Detailed notes
## Background Published on YouTube by game developer Casey Muratori on May 12, 2016, this video documents his 2005 presentation introducing the immediate-mode graphical user interface (IMGUI) paradigm. The description directs viewers to his personal blog at caseymuratori.com/blog_0001 for additional details and context.
## TL;DR Muratori details the architecture of immediate-mode graphical user interfaces (IMGUI), a paradigm he originated while developing tools at RAD Game Tools to replace the brittle callbacks, redundant state caches, and boilerplate of traditional retained-mode frameworks. Drawing a direct parallel to immediate-mode 3D graphics pipelines, the system evaluates layout, rendering, and user input simultaneously every frame using standard language control flow. By tracking interaction through a minimal global context with 'hot' and 'active' widget IDs, the application retains full ownership of its data without needing complex widget object hierarchies. While the approach introduces trade-offs like a single frame of layout latency and the need for coarse-grained application culling in C/C++, it dramatically simplifies custom controls, animated dynamic interfaces, and 3D rendering integration.
## Atmosphere & style The presentation has an intimate, unvarnished, and hands-on workshop feel, opting for hand-drawn marker sketches on giant sheets of paper instead of polished digital slides or formal academic lectures. Muratori speaks with casual, candid conviction, punctuating architectural breakdowns with dry humor about industry bugs and the exasperation of fighting standard UI toolkits. It feels like an authentic peek into an engineer's notebook—pragmatic, direct, and driven by a genuine passion to share a simpler way to build software.
## Bulletin - [00:01](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1s) Casey Muratori formalizes Immediate-Mode Graphical User Interfaces (IMGUI), an alternative UI paradigm developed around 2002 that dispenses with retained widget hierarchies, initialization routines, and event-dispatch callbacks in favor of procedural per-frame execution. - [12:02](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=722s) The entire interaction model of an IMGUI system is governed by a global UIContext tracking just two states—'hot' (hovered/about to be interacted with) and 'active' (currently engaged)—eliminating redundant state cached across inactive widgets. - [20:43](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1243s) IMGUI mirrors modern graphics pipelines by treating UI as an imperative draw stream, allowing seamless embedding inside 3D rendering loops and dynamic animation transforms without scene-graph synchronization. - [32:46](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1966s) Key engineering trade-offs include a potential one-frame latency for global layout calculations in languages like C/C++ lacking introspection, as well as shifting coarse-grained culling responsibilities onto application code.
## Key takeaways - [01:49](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=109s) IMGUI originated organically during tool development for Granny 3D at RAD Game Tools to escape the boilerplate and fragility of traditional UI engines. - [03:18](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=198s) Retained-mode UI architectures suffer from a fundamental disconnect across three fragmented phases: widget initialization, internal black-box updates, and asynchronous callback handling. - [04:10](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=250s) In retained UI systems, application data is repeatedly duplicated and synchronized across persistent widget class instances, creating fragile ID mappings and manual state tracking. - [06:34](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=394s) IMGUI operates analogously to immediate-mode rendering APIs: controls are submitted, evaluated, and rendered procedurally on each frame within the main application loop. - [07:15](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=435s) Standard language control-flow constructs (if, switch, for, while) directly govern UI visibility and generation, eliminating dynamic create/destroy calls. - [09:25](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=565s) Traditional widgets store massive amounts of redundant state (e.g., inactive edit boxes caching text cursor and selection machinery), whereas a user can only physically engage with one widget at a time. - [12:02](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=722s) Interactive state across almost all widgets collapses into two context identifiers: 'hot' for hover focus and 'active' for active engagement. - [13:29](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=809s) Global ID maintenance is replaced by passing arbitrary caller-side tokens (such as function pointers, owner struct pointers, or array indices) into widget calls. - [16:49](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1009s) A standard button widget evaluates active status, mouse release, hover conditions, and draw calls within a single inline function, returning a simple boolean to execute actions in place. - [18:23](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1103s) When a widget is active, other controls are prevented from becoming hot, ensuring clean input isolation across the interface. - [23:55](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1435s) IMGUI eliminates existence synchronization: culling a control or an entire panel merely requires skipping the function invocation for that frame. - [27:01](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1621s) Custom and specialized widgets are trivial to author because developers only need to coordinate with the active/hot state and are otherwise unconstrained in rendering and input logic. - [29:01](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1741s) Immediate-mode UI integrates natively with 3D engines, allowing ray-casting and scene picking to substitute directly for 2D bounding-box hit tests without subclassing vendor UI wrappers. - [31:08](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1868s) Dynamic and animated interfaces (such as controls tracking moving 3D character joints) work seamlessly because coordinates and state are re-evaluated anew on every frame. - [32:46](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1966s) Because languages like C and C++ lack code reflection, aggregate layout dimensions cannot be known prior to execution, requiring multi-pass measurements or accepting a single frame of layout latency. - [36:15](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=2175s) Fine-grained dirty-region updates are difficult in IMGUI, shifting responsibility to the host application to perform coarse-grained visibility culling before dispatching UI calls.
## Detailed walkthrough ### [00:01](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1s) Introduction to Immediate-Mode Graphical User Interfaces
Casey Muratori introduces the presentation as hopefully the first installment in a series of informal programming videos. At his studio, Molly Rocket, he frequently experiments with unconventional techniques as part of development for their upcoming and future games. Because preparing formal academic papers or polished, professional lectures is too time-consuming, he opts for an informal format: sketching makeshift slides on giant sheets of paper and talking through the core concepts in front of a video camera to disseminate the information efficiently.
The topic of this session is immediate-mode graphical user interfaces (IMGUI), a technique he began developing around 2002. Rather than relying on traditional object-oriented class libraries, IMGUI is a coding paradigm for building user interfaces—whether for desktop tools, games, or general applications—that is substantially easier to write, read, and reason about. Muratori notes that while the idea has fundamentally reshaped how he constructs software, he wants to share the overview widely to see whether other developers find it equally transformative or if it merely reflects his personal coding idiosyncrasies.
- **Origin date**: Developed around 2002 by Casey Muratori. - **Context**: Used at Molly Rocket during game development to replace complex object-oriented widget hierarchies. - **Format**: Makeshift hand-drawn paper slides recorded directly on camera to bypass the overhead of writing formal academic papers.
---
[01:49](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=109s) The Frustration with Traditional UI and the Genesis at RAD Game Tools
Muratori explains the frustration that drove him to seek an alternative approach. Having implemented user interfaces across various platforms—including the Windows API, X Window System, and custom UI engines—he found the experience universally miserable. Developers routinely found themselves wrestling with clunky visual layout editors, tracking IDs across disparate files, managing event callbacks, and maintaining fragile linkages between UI elements and underlying application data. The sheer volume of boilerplate code required to put even basic widgets on screen felt entirely disproportionate to the task.
The breakthrough occurred organically rather than through a deliberate research effort. While working at RAD Game Tools on the animation viewer for Granny 3D, Muratori had to incorporate numerous interactive controls. As he built the tool, he realized the entire process could be dramatically streamlined:
> “I didn't intentionally try to address it I wasn't set out to try and fix this problem but what happened was I was working on at RAD Game Tools I was working on doing the viewer for Granny which had a lot of different kind of UI components to it and as I was working on it it sort of hit me that the way that I was doing things could be simplified quite a bit and so I started trying to do some of the simplifications and I found that it was kind of just like a completely new a completely fresh way of coding the user interfaces that was just so much more natural to me and so ever since then that's the only way I've ever done user interfaces.”
---
[03:18](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=198s) The Anatomy and Pitfalls of Traditional Retained-Mode UI
To highlight why traditional architectures fail, Muratori breaks down the lifecycle of standard retained-mode UI libraries. Under this paradigm, application code is fragmented across three completely distinct phases: initialization, update, and event dispatch. At initialization time, the developer executes a barrage of widget creation calls or deserializes layout files exported from a WYSIWYG editor to instantiate buttons, dialogs, and property sheets. During update time, the UI library operates as an opaque black box, handling its own internal state, hit-testing, and rendering without the developer's direct knowledge or intervention (outside of awkward hooks like owner-draw routines).
```mermaid flowchart TD accTitle: Traditional Retained-Mode UI Architecture accDescr: Diagram illustrating the fragmented lifecycle of retained UI with separate Init, Hidden Update, and Callback phases.
subgraph InitPhase["Initialization Phase"] A["Load Layout / Create Widgets"] --> B["Register Control IDs"] end
subgraph BlackBox["UI Library Runtime"] C["Internal UI Loop"] --> D["Event Detection & State Tracking"] end
subgraph EventPhase["Callback / Message Phase"] E["Callback / Window Proc"] --> F["Query Widget by ID"] F --> G["Synchronize App State"] G --> H["Dynamically Enable/Create/Destroy Controls"] end
B -.-> C D --> E H -.-> C ```
The third phase occurs when user interaction triggers a callback or pushes a message into an event queue. Because the application logic is separated from the controls, the callback handler must query the widget by a shared integer ID or pointer to retrieve its current value and copy that state into application variables. Furthermore, if an interaction causes the interface to alter its layout—such as switching a tab, presenting a new dialog, or toggling control availability—the developer must intersperse dynamic creation, destruction, and enable/disable calls within event handlers. This architecture decentralizes control, forcing IDs and state management to be coordinated across separate initialization routines, callback handlers, and external layout resources:
> “In the bad case like if you're using say for example any of the Microsoft tools you're a deep trouble you end up writing hundreds of lines of code that essentially does nothing other than keeping all of this stuff kind of wrangled together.”
- **Initialization phase**: Requires explicit instantiation (`CreateButton`, dialog templates, resource files) to populate widget hierarchies. - **Update phase**: Completely internal to the UI library; developer has little control over layout or draw operations. - **Callback phase**: Must route through message handlers or callbacks, look up widgets via IDs, manually read values back into application state, and manage lifetime state changes dynamically.
---
[06:34](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=394s) The Immediate-Mode Paradigm: Drawing from Graphics Architecture
Muratori contrasts this fractured workflow with the immediate-mode philosophy. In an immediate-mode graphical user interface, there is no initialization step for UI elements, no external state cache maintained by widgets, and no asynchronous callbacks. Instead, the UI is declared procedurally each frame within a primary update path authored directly by the developer. Much like immediate-mode rendering APIs where geometry is submitted directly per frame rather than built into a persistent scene graph, an immediate-mode UI evaluates interaction and rendering concurrently in place.
Under this model, interacting with a control is as simple as evaluating an expression inline:
```c if (DoButton(...)) { // Execute click action immediately } ```
If the user clicked the button during that frame, `DoButton` returns true and executes the dependent application logic immediately in that exact lexical scope; simultaneously, the call handles the visual presentation of the button on the screen. Because UI execution mirrors standard procedural programming, developers can freely wrap controls in standard control-flow constructs—using standard `if` statements for conditional visibility, `switch` statements for property pages, and `for` or `while` loops to generate dynamic lists of interactive controls directly from application memory.
Muratori emphasizes that despite any initial unfamiliarity, the concept rests on a proven historical shift in computer graphics:
> “That's the only key difference between immediate mode user interfaces and standard user interfaces is they're just trying to do what immediate mode graphics did as compared to retained mode graphics because we all pretty much know how hard retain mode graphics suck that's why we use immediate mode graphics same is true of immediate mode user interface I think regular graphic interfaces which are retained you do inits you have them they know state they know what what their button is whatever I think those suck and immediate mode graphical user interfaces are kind of the answer in my opinion.”
| Feature | Retained-Mode UI | Immediate-Mode UI (IMGUI) | |:--- |:--- |:--- | | **Widget State** | Stored and duplicated inside widget class instances | Driven directly by existing application data | | **Execution Flow** | Fragmented across `Init`, event callbacks, and framework loops | Single unified update path inside the main application loop | | **Control Flow** | Dynamic creation/destruction API calls, show/hide state toggles | Native language control flow (`if`, `switch`, `for`, `while`) | | **ID Management** | Central ID registries, strings, or pointers shared across files | Minimal or handled implicitly via call context | | **Mental Model** | Retained scene graph with synchronized mirror states | Immediate-mode rendering pipeline |
[09:25](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=565s) The UI Context and Exploiting Redundant State
Casey Muratori introduces a practical implementation of an immediate-mode graphical user interface, emphasizing that while the core concept can be realized in countless ways, his approach revolves around a central structure known as the `UIContext`. This context exists to track the user's interaction state with the system at any given moment. Muratori argues that standard retained-mode UI architectures are plagued by an overlooked architectural flaw: an immense amount of redundant state stored across individual widgets. For instance, a retained-mode edit box typically holds all the state machinery required to edit text—cursor position, mouse history, click tracking, and selection ranges—even when the user is not actively interacting with it. If two edit boxes appear on screen simultaneously, the user can only ever type in one at a time. The inactive edit box merely needs to know what text string to draw, yet it retains all the baggage of an active text editor.
While memory consumption is rarely the primary bottleneck in GUI development, Muratori jokes that developers who have used Visual Studio might remember clicking a tree node only to be greeted by a dialog warning that the action “may take a long time to expand.” The deeper realization is that recognizing redundant state enables a radical simplification of the codebase:
> “The point is that redundant state is actually something that can be exploited to make a much more efficient piece of code that's simpler and easier to understand...”
Because a user can only physically engage with one widget at a time, the entire GUI can be governed by a single global structure representing interaction state. Everything else belongs to the application. An edit box should never own or duplicate the string it displays; that string already possesses domain-specific meaning and lives inside the application's own data structures. By stripping widgets of duplicate application data, the UI needs to retain only the bare minimum required to conduct interactive input.
[12:02](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=722s) Hot and Active State: The Core Interaction Model
To model user interactions across almost any widget—from simple buttons and menu items to complex inputs—the `UIContext` requires two fundamental state fields: `hot` and `active`. These fields use an identifier structure (`UIID`) to point to the widget currently occupying each role:
- **Hot**: The item the user is *about* to interact with. For mouse-driven interfaces, this means the cursor is hovering directly over the widget's bounding box; in keyboard-driven interfaces, it denotes the currently highlighted element. Visually, a hot item updates its appearance (e.g., highlighting or brightening) to indicate to the user that it is ready to receive input. - **Active**: The item the user is *actually* interacting with. This state begins the moment the user initiates a concrete input gesture on that element, such as depressing the mouse button down over it.
```mermaid flowchart TD accTitle: Hot and Active State Transitions accDescr: State flow showing how mouse interactions drive a UI element through hot, active, and triggered states.
subgraph IdleState["Not Engaged"] None["Default Widget State"] end
subgraph HotState["Hovering"] Hot["Item is Hot<br/>(Render Highlighted)"] end
subgraph ActiveState["Interacting"] Active["Item is Active<br/>(Mouse Down on Item)"] end
subgraph CompleteState["Fired"] Trigger["Mouse Up Over Item<br/>(Action Triggered: Return True)"] end
None -->|"Mouse moves over"| Hot Hot -->|"Mouse leaves"| None Hot -->|"Mouse button pressed"| Active Active -->|"Mouse released over item"| Trigger Active -->|"Mouse released outside item"| None Trigger --> None ```
Muratori explains the critical distinction:
> “Hot means like about to be interacted with and active means I'm actually interacting with it.”
Together, `hot` and `active` form almost the entirety of the global state needed to run basic user interface widgets in immediate mode.
[13:29](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=809s) Identifying Widgets Without Global ID Hell
In traditional retained-mode GUI frameworks, widgets require globally unique identifiers (often managed via rigid resource tables, enums, or header files) so disparate sections of application code can find a control created in one place and query its data somewhere else. In an immediate-mode system, this entire problem evaporates. Because all application data flows directly through the UI call site and is kept within application memory, code never needs to reach into GUI controls to extract state.
However, identifiers are still necessary for the GUI library to distinguish which widget was hot or active across successive frames. Rather than forcing developers into header-file ID management, Muratori relies on passing arbitrary caller-side data into widget calls to serve as a `UIID`:
- **Function Pointers**: A pointer to the callback or handler function invoked by a button can act as its unique ID. If multiple buttons perform the exact same command, sharing this identifier might even be desirable so all related elements react synchronously. - **Owner Pointers**: If distinct instances share identical functionality or labels, an owner pointer—such as a pointer to the surrounding container function or the backing data struct driving that section of the UI—disambiguates them. - **Indices**: When generating widgets inside a loop or array, an integer index combined with an owner pointer guarantees uniqueness.
Muratori points out that this system directly mirrors immediate-mode graphics APIs (such as OpenGL feedback or selection buffers), where the graphics system treats picking tokens as blind application data without needing to understand or manage their structure.
[16:49](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1009s) Inside the Immediate-Mode Button Logic
Muratori examines the internal logic of a standard widget function, such as `DoButton`, as implemented within the UI library itself. To the caller, `DoButton` is a clean call taking the `UIContext`, an identifier (`UIID`), label text, and layout coordinates, returning a simple boolean: `true` if the button was activated this frame, `false` otherwise.
Under the hood, the widget executes a concise state check:
1. **Active Check**: It queries the `UIContext` to check if its identifier matches the currently active ID. 2. **Release / Click Validation**: If it is the active item and the mouse button has just been released, it checks if it is also the `hot` item (verifying the cursor is still hovering over the button). If both hold true, the interaction was successful, and the function flags that it will return `true` to signal the application to execute the button's action. 3. **Deactivation**: Regardless of whether the cursor was over the button at the moment of mouse release, releasing the mouse button clears the active state, returning the item to inactive.
Muratori emphasizes that callers write no state-machine boilerplate:
> “I talked about do button and I was saying that it returns a bool which is true if the button was clicked so you know to do something when you called it...”
The entire life cycle of click detection, drag-away cancellation, and visual feedback collapses into a few lines of logic executed directly during the layout and drawing pass.
[18:23](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1103s) Button Mechanics: Hit Testing, Hot States, and Active States
Casey walks through the canonical behavior of a button widget to explain how the hot/active model works. A standard button click requires the user to press down while over the button and then release while still over the button. If the user presses down over a button and then drags away before releasing, that interaction must not trigger an action. While this is standard operating procedure for desktop user interfaces, Muratori points out dryly that “it'd be weird if you did something else, your users would get a little confused, although many games often don't implement that correctly; what are you going to do?”
```mermaid flowchart TD accTitle: Button Interaction Logic accDescr: State decision tree for handling mouse input on a button widget
subgraph Evaluation ["Per-Frame Widget Evaluation"] A["Is widget active?"] B{"Mouse released?"} C{"Is widget hot?"} D["Return TRUE (Click action)"] E["Clear active state"] F{"Is widget hot & mouse down?"} G["Set widget as ACTIVE"] end
subgraph HitTest ["Hit Testing & Hover"] H{"Mouse inside bounds?"} I{"Is any widget active?"} J["Set widget as HOT"] K["Do not set hot"] end
A -->|Yes| B B -->|Yes| C C -->|Yes| D C -->|No| E D --> E B -->|No| H A -->|No| F F -->|Yes| G F -->|No| H G --> H H -->|Yes| I I -->|No| J I -->|Yes| K ```
When a button is evaluated and it is not currently active, the code checks if it is hot. If the user clicks down while the button is hot, the button immediately transitions into the active item. Once marked active, subsequent frames track that interaction until the mouse button goes up. If the cursor is inside the button's boundary, it requests to become hot via a helper function:
- Setting the active state directly claims user input for that widget until release. - Requesting the hot state (`set_hot`) checks whether *any* widget is currently active; if an item is already active, no other widget is permitted to become hot, preventing unrelated controls from lighting up or reacting while another control is being manipulated. - Following the logic pass, the widget function issues standard drawing commands (rendering the button frame, rounded corners, label text) within the library rather than in client-side code.
[20:43](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1243s) The Retained-to-Immediate Parallels in 3D Graphics and UI
Expanding beyond basic buttons, Muratori notes that while simple widgets (like scrollbars) follow identical hot/active patterns, complex controls like text edit boxes need interim data stored during their active lifetimes. The UI context can track cursor positions, drag selections, and character offsets for active widgets, extending the paradigm without altering its core architecture.
Drawing an explicit historical comparison, Muratori connects immediate-mode UI to the graphics industry's shift away from retained-mode scene graphs in the 1990s and early 2000s. In modern rendering, game engines run custom per-frame loops that iterate over objects, sort batches, draw opaque geometry, traverse BSP trees, handle transparency, and cull invisible elements. Casey highlights that “that was a very important part of the progress of graphical coding is realizing that retained mode was not a good thing because the important way the way that the app needs to express how things get drawn is necessarily going to look like this; it needs the flexibility there to do whatever it wants.”
```mermaid flowchart LR accTitle: Application-Driven UI Generation accDescr: Flow showing application data driving immediate-mode UI rendering without retained intermediates
subgraph AppSide ["Application Logic (Full Control)"] A["App State / Data Source"] --> B["Iterate Collections"] B --> C{"Cull or Filter?"} C -->|Skip| D["Skip Call"] C -->|Draw| E["Call do_item() / do_menu()"] end
subgraph IMGUI ["Immediate-Mode UI Library"] E --> F["Immediate Interaction Test"] E --> G["Immediate Render Pass"] F --> H["Return Action / Result"] end ```
UI should mirror this exact workflow. An application developer should simply write loops over internal data structures—menus, submenus, pop-ups, or custom lists—calling widget functions on the fly without declaring them ahead of time. Culling in this context is effortless: if an item should not appear, the program simply skips calling `do_item()` for that frame. Skipping the call automatically removes the visual representation and disables user interaction without requiring explicit hide, disable, or delete calls.
[23:55](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1435s) Core Advantages: Unified Flow Control and Zero Synchronization
Muratori outlines the foundational architectural benefits that make immediate-mode GUIs vastly superior to traditional retained-mode object frameworks:
1. **Single Piece of Code per Logical Unit**: Rather than fracturing a UI element across a visual layout file, initialization routines, update handlers, and message callbacks, an immediate-mode widget puts layout, rendering, interaction, and reaction in a single location: “All you have to do is just write a single piece of code which encapsulates where something's drawn, how it's drawn, how it's interacted with, and what you want to do when that interaction comes through; it's all in one place.” 2. **Unified Flow Control**: Traditional GUIs hijack program flow through external event loops and asynchronous callbacks. In an immediate-mode system, the application remains fully in control, driving the path of execution to mirror its own architectural structure and receiving return values synchronously. 3. **Elimination of State Synchronization**: Retained frameworks spend enormous amounts of boilerplate code pushing values across boundaries: calling setters, toggling visibility flags, and tracking whether objects match the internal data model. In immediate mode, there is zero existence synchronization. If a gameplay condition changes or a timer expires, the application simply stops calling that property sheet's rendering function, and it instantly ceases to exist:
> “Now you only have to worry about your own part of the code, your own logic; you don't have to worry about making sure that your own logic can be mapped onto the UI logic in some way, which typically is a huge headache and involves a lot of extraneous code that is boring and really contains no valuable information.”
[27:01](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1621s) Specialized Widgets and Dynamic Item Relationships
Casey Muratori explains that standard user interface libraries handle complicated widgets with specialized behaviors exceptionally poorly. In typical frameworks, the moment an application needs a highly customized control unique to its workflow, the architecture breaks down. In contrast, an immediate-mode GUI accommodates custom interactivity trivially: developers can simply write their own widget logic and rendering code right inline, or encapsulate it into helper functions as an internal secondary library. Because the system hinges solely on UI context state, custom controls only need to coordinate with the active and hot item tracking. As Casey notes: “You just as soon as you feel like your widget became active you set it to the active item, everything else in the UI is shut down until you release that activeness, so you can write any code that you want.” Once a control claims active status, the developer has total freedom over mouse interaction and rendering without worrying about interfering with the rest of the interface.
This flexibility scales naturally to complex, dynamic relationships between items, which retained-mode systems handle awkwardly. Reordering buttons, hiding entire sections behind a checkbox, or rendering complex panels only under specific conditions typically requires registered callbacks, change notifications, and manual calls to construct, modify, or tear down widget subtrees. In immediate mode, dynamic visibility is collapsed down to standard control flow: if a set of widgets should only appear when a variable equals five, the programmer simply wraps those widget calls in `if (value == 5) {... }`. Because the UI is executed procedurally every frame, state checks and visibility rules match the program's native logic without any synchronization boilerplate.
```mermaid flowchart TD accTitle: Retained-mode vs Immediate-mode Conditional UI accDescr: Comparison showing how retained-mode requires event handlers and explicit tree mutations versus immediate-mode using native if-statements.
subgraph Retained["Retained Mode"] R_Event["Value Changed Event"] --> R_CB["Run Registered Callback"] R_CB --> R_Check{"Check Value == 5"} R_Check -->|"True"| R_Add["Construct/Attach Widgets to Tree"] R_Check -->|"False"| R_Rem["Detach/Destroy Widget Subtree"] end
subgraph Immediate["Immediate Mode"] I_Check{"if (value == 5)"} I_Check -->|"True"| I_Call["Call Widget Functions Directly"] I_Check -->|"False"| I_Skip["Do Nothing (Skipped this frame)"] end ```
[29:01](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1741s) Integrating Seamlessly with 3D Renderers and Non-UI Subsystems
Immediate-mode GUIs offer enormous advantages to game developers and creators of 3D editing tools because they integrate directly with subsystems that possess no built-in knowledge of user interfaces. Systems like 3D animation rigs or renderers are never authored with UI concepts in mind, yet they almost universally support viewport ray-picking and drawing routines. Turning these systems into interactive controls requires minimal glue code: rather than using standard 2D axis-aligned bounding box hit-testing (`is_inside_rectangle`), an immediate-mode button function can directly query the 3D renderer's scene picking or ray-cast test.
Because UI invocations are simple procedural calls, developers can embed user interface commands directly inside sophisticated rendering loops—such as loops that manipulate camera matrices, scene graphs, and lighting states. Conventional object-oriented UI toolkits make this integration excruciating, forcing programmers to derive from library base classes while hoping the vendor exposed sufficient virtual methods, events, and context hooks. In practice, callbacks trigger out of order and context management collapses, forcing many commercial applications into a broken compromise. As Casey points out: “It's just a disaster to the point where even in professional 3D applications often times you have two totally separate systems running the user interface—one for the 2D user interface, one for the 3D user interface.” In an immediate-mode architecture, both paradigms collapse into a single unified execution path.
- Retained-mode frameworks require subclassing vendor classes and relying on fragile message-dispatch or event-hook mechanisms. - Immediate-mode systems allow standard 3D picking functions to substitute for 2D mouse-hit tests inside custom widget functions. - Camera transformations, model matrices, and scene rendering can wrap UI calls naturally without state synchronization issues.
[31:08](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1868s) Real-Time Dynamics and Moving Interfaces
Immediate-mode design aligns naturally with real-time applications because the UI hierarchy is completely reconstructed and submitted on every single frame. Rather than maintaining static layouts in memory, the interface executes in lockstep with the frame update. This architecture makes animating controls trivial: if an animation system drives an in-game character, a button can easily track a dynamic point above the character's head by querying the joint transform and calling the button function using those exact coordinates. Because state is evaluated instantaneously, partitioning bugs and transform synchronization problems vanish entirely.
This capability is particularly vital as user interface design trends toward rich, kinetic presentation layers, popularized by platforms like Mac OS X and web-based Flash animations. Users increasingly expect dynamic elements that slide, float, and react fluidly across the screen. These animated layouts impose immense bookkeeping overhead on traditional UI frameworks, which are optimized around stationary controls. In contrast, an immediate-mode system thrives on motion, as its core mechanics assume that screen coordinates and widget parameters are ephemeral values provided anew on every frame.
[32:46](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1966s) Language Limitations, Frame Lag, and Architectural Trade-Offs
Despite its decisive advantages, immediate mode introduces specific trade-offs stemming primarily from the limitations of languages like C and C++. Because C and C++ do not treat code as data and lack native reflection, introspection, and closures, an application cannot introspect its UI structure without actually calling the functions. Casey explains the root cause of this structural constraint: “You have to actually execute the UI to know what the UI is, and that's where a lot of the power of immediate-mode graphical user interfaces come from, but it also means there are some drawbacks.” A program cannot inspect the aggregate bounds of a layout beforehand unless it runs the layout execution path first.
Consequently, operations that depend on knowing the global dimensions of a widget hierarchy before positioning elements inherently suffer from a single frame of latency unless multi-pass strategies are introduced. While a developer can implement two passes via the UI context—running one pass in layout mode where widgets merely measure their dimensions, followed by a rendering pass—this pattern reintroduces complexity and drifts away from the paradigm’s core simplicity. In interactive real-time graphics, a one-frame layout delay is virtually imperceptible, making the single-frame lag an acceptable engineering compromise for most use cases. Beyond layout latency, the only other notable trade-off is the responsibility placed on the host application if it wishes to throttle redraws and avoid executing the UI every frame when the display is idle.
- C and C++ lack language introspection, meaning the UI tree exists only as dynamic control flow during execution. - Global layout calculations require either accepting a one-frame lag or executing a multi-pass system (layout measurement pass followed by a rendering pass). - Multi-pass execution can be tracked via flags in the UI context, but adds code complexity that compromises the paradigm's inherent minimalism. - Retained-mode systems can inspect and iterate over existing widget object hierarchies repeatedly, bypassing the single-frame layout latency constraint.
[36:15](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=2175s) Rendering Trade-Offs and Application-Level Culling
When an interface becomes exceptionally complicated to render, redrawing every element on every single frame can become a bottleneck. Under a traditional retained model, systems frequently optimize this by isolating changed widgets and only repainting dirty rectangles. In an immediate-mode GUI, however, achieving that fine-grained isolation is much harder because the user interface is generated dynamically from the imperative flow of application code.
As a result, handling selective redraws or avoiding unnecessary UI processing shifts back to the application programmer. Casey Muratori compares this dynamic directly to how 3D graphics engines handle scene rendering: the underlying API does not magically guess what needs to be drawn, so the application itself must perform coarse-grained culling before dispatching work. If an entire window or sub-panel is closed or completely off-screen, the application must take responsibility for skipping that block of UI calls altogether.
```mermaid flowchart TD accTitle: IMGUI Rendering Control Flow accDescr: Diagram illustrating coarse application-level culling versus fine-grained immediate mode widget evaluation.
subgraph AppLevel["Application Level (Coarse Culling)"] CheckVis["Is Sub-panel / Window Visible?"] Skip["Bypass UI Function Calls"] Exec["Execute Block of UI Code"] end
subgraph IMGUILevel["IMGUI Framework Level"] Layout["Compute Layout & State"] Render["Dispatch Dynamic Drawing Calls"] end
CheckVis -- No --> Skip CheckVis -- Yes --> Exec Exec --> Layout Layout --> Render ```
- In immediate-mode systems, fine-grained dirty-region updates are difficult to isolate because interfaces are generated inline by program control flow rather than stored as static scene graphs. - Coarse-grained culling mirrors 3D engine architectures: “The application is responsible for doing those sorts of things at the coarse level, and the same would be true of IMGUI, so again a couple trade-offs there.”
---
[36:58](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=2218s) The Potential of Immediate Mode and Community Evolution
Reflecting on the system as a whole, Casey emphasizes that despite these trade-offs, immediate-mode GUIs offer compelling advantages that warrant wider experimentation across the software industry. Traditional retained-mode GUI architectures have benefited from decades of widespread industrial use, academic research, and iterative refinement. In contrast, the techniques Casey describes were developed essentially in his spare time to satisfy his own immediate, practical project requirements, without any dedicated institutional backing.
The fact that the model already functions so effectively despite receiving only limited, ad-hoc development makes Casey optimistic about its future. He argues that if the wider programming community begins actively using, probing, and developing libraries around immediate-mode ideas, developers will invent solutions to edge cases that he has not yet encountered or considered.
- Traditional GUI paradigms have accumulated decades of dedicated engineering and evolution. - IMGUI was assembled purely during Casey's spare time for specific internal use cases, yet it rapidly reached a viable, highly functional state. - Casey summarizes his optimism regarding broader adoption: “Standard graphical user interface libraries have had many, many, many years of evolution, and this has only had, you know, basically my time, which has not even been dedicated to it, and it's already gotten pretty far, which makes me think that it's a decent way of doing things because it's so easy to make progress there.”
---
[37:52](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=2272s) External Resources, Sean Barrett's Articles, and Molly Rocket Forums
Information on immediate-mode graphical user interfaces remains scarce because very little written material has been published on the topic. Casey notes that Sean Barrett is preparing a series of in-depth articles on IMGUI for *Game Developer Magazine*, which will include accompanying implementation code so programmers can see a concrete system running in practice. While Casey and Sean previously discussed the concept, their specific architectural approaches and styles may have diverged over time, making Sean's upcoming pieces a valuable alternative perspective.
Beyond print articles, Casey hopes commercial libraries implementing immediate-mode paradigms will emerge in the future, noting rumors that some developers are exploring the space. To foster discussion around the video and answer lingering technical questions that this brief overview could not address, Casey directs viewers to the lecture section of the Molly Rocket forums.
- Sean Barrett’s upcoming articles and sample code are slated for *Game Developer Magazine* (`www.gdmag.com`) and his personal website (`www.nothings.org`). - Casey admits that aside from informal peer discussions with developers who found the concept intriguing, very little public documentation exists: “I haven't done much to disseminate this, and I apologize for that, so as a result there's not that much available about it, there really aren't any articles.” - Discussion, Q&A, and follow-ups are hosted on the Molly Rocket website forums at `www.mollyrocket.com/forums` within the dedicated lectures area.
## Notable quotes > [23:55](https://www.youtube.com/watch?v=Z1qyvQsjK5Y&t=1435s) All you have to do is just write a single piece of code which encapsulates where something's drawn, how it's drawn, how it's interacted with, and what you want to do when that interaction comes through; it's all in one place. — Casey Muratori
## Mentioned Casey Muratori, Molly Rocket, RAD Game Tools, Granny 3D, Windows API, X Window System, Visual Studio, OpenGL, Mac OS X, Flash, Sean Barrett, Game Developer Magazine
## Video description For more details, see https://caseymuratori.com/blog_0001
[Source](https://www.youtube.com/watch?v=Z1qyvQsjK5Y)