# What Is the Core Concept Behind ImGui's Immediate Mode GUI?

> Discover ImGui's immediate mode GUI core concept. Build UIs from scratch each frame with direct commands for deterministic, code-driven interfaces. Learn more.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: deep-dive
- Published: 2026-07-16

---

**ImGui's immediate mode GUI paradigm constructs the user interface from scratch every frame by issuing direct UI commands that return interaction state immediately, eliminating persistent widget hierarchies and enabling deterministic, code-driven interfaces.**

ImGui (Dear ImGui), developed by Omar Cornut in the `ocornut/imgui` repository, revolutionizes interface design through the **immediate mode GUI** approach. Unlike traditional retained-mode toolkits that maintain persistent widget objects in memory, ImGui rebuilds the entire interface each frame based on your application's current state. This architecture places UI code directly alongside logic, making it ideal for debugging tools, game engines, and real-time applications.

## How Immediate Mode GUI Works in ImGui

### Stateless UI Calls Every Frame

In ImGui's immediate mode GUI, your application issues UI commands directly inside the render loop. Functions like `Button()`, `SliderFloat()`, and `Begin()` describe what should appear on screen **right now** and immediately return the current interaction state. For example, `Button()` returns a boolean indicating whether the user clicked during this frame.

```cpp
// imgui.h - core API declaration
IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0));

```

According to the `ocornut/imgui` source code, these declarations in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) contain no persistent objects—just immediate function calls that query and return state.

### Internal State Management via ImGuiContext

While your code remains stateless, ImGui maintains necessary UI state (hovered items, active widgets, input focus) in global structures within `ImGuiContext`. The library updates this state as it processes your immediate calls, but **no widget objects are allocated by user code**. This implementation resides in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), specifically within `ImGui::NewFrame()` and `ImGui::Render()`.

### Deterministic Rendering Without Retained Objects

Because the immediate mode GUI is rebuilt from scratch each frame, the visual output is always a deterministic function of the current application state and your immediate UI calls. This eliminates entire classes of bugs related to stale widget state or synchronization issues common in retained-mode frameworks.

### Backend Agnostic Architecture

The immediate mode core knows nothing about underlying graphics APIs. Backends such as [`imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_opengl3.cpp) and [`imgui_impl_vulkan.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_vulkan.cpp) translate the draw lists produced by `ImGui::Render()` into actual GPU commands, keeping the GUI logic completely separate from rendering implementation.

## The Frame Lifecycle in ImGui's Immediate Mode GUI

Every frame follows a simple two-step process defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h):

```cpp
ImGui::NewFrame();            // Prepare a new UI frame, reset state
// ... issue immediate UI calls ...
ImGui::Render();              // Generate draw data for the backend

```

This minimal lifecycle makes integration straightforward. You drive the UI within your existing game loop or application update function without managing complex widget hierarchies or event callbacks.

## Benefits of Immediate Mode GUI in ImGui

ImGui's implementation of the immediate mode GUI paradigm delivers several architectural advantages:

- **Ease of use**: UI code lives next to the logic that drives it. You can read and write UI state in the same place, eliminating the need for separate callback functions or observer patterns.

- **No retained objects**: You never manage lifetimes of widget objects, reducing memory-leak risk and removing the need for complex destruction hierarchies.

- **Fast iteration**: Changing UI layout only requires editing the immediate calls. The library recomputes everything each frame, so changes are visible instantly without rebuilding widget trees.

- **Predictable behavior**: Interaction results are available immediately after the widget call returns. For example: `if (ImGui::Button("OK")) { /* action */ }`.

- **Low overhead**: The library stores only minimal state in `ImGuiContext`. Most work involves simple per-frame arithmetic and draw-list generation in [`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp).

## Practical Immediate Mode GUI Patterns

### Creating Windows and Buttons

This pattern from [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) demonstrates the basic window workflow:

```cpp
ImGui::Begin("Demo Window");                     // Start a window
if (ImGui::Button("Press Me")) {                // Immediate call returns true on click
    std::cout << "Button clicked!\n";
}
ImGui::End();                                   // Finish the window

```

The `Begin()` and `End()` pair creates a container that exists only for this frame.

### Direct State Manipulation with Sliders

Widgets directly modify application variables through pointers:

```cpp
static float value = 0.5f;                      // Persistent variable owned by the app
ImGui::SliderFloat("Opacity", &value, 0.0f, 1.0f);
// 'value' updates automatically each frame based on user interaction

```

The underlying `SliderScalar` logic in [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp) handles the immediate-mode interaction while your variable persists in your own code.

### Dynamic Hierarchical Views

Immediate mode naturally handles dynamic content without precalculation:

```cpp
if (ImGui::TreeNode("Settings")) {
    ImGui::Checkbox("Enable feature", &g_EnableFeature);
    ImGui::Combo("Mode", &g_Mode, "Easy\0Medium\0Hard\0");
    ImGui::TreePop();
}

```

Since the tree is built every frame, you can change structure based on runtime conditions without managing node lifetimes.

## Summary

- ImGui implements an **immediate mode GUI** where widgets are function calls rather than persistent objects, defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) and implemented across [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) and [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp).

- The architecture requires only `NewFrame()` and `Render()` calls per frame, with backends like [`imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_opengl3.cpp) handling actual GPU output.

- All widget state lives in `ImGuiContext` structures managed internally, while user code remains stateless and deterministic.

- **Immediate return values** from functions like `Button()` and `SliderFloat()` enable tight coupling between UI presentation and application logic.

- This approach eliminates retained-mode complexity, reduces memory overhead, and supports rapid iteration on interface design.

## Frequently Asked Questions

### What is the difference between immediate mode GUI and retained mode GUI?

In an **immediate mode GUI**, the application issues UI commands every frame that describe the current state of the interface, and widgets return interaction results immediately. In a **retained mode GUI**, you construct a persistent hierarchy of widget objects that store their own state and render independently, requiring event callbacks and synchronization between your data and the UI objects.

### How does ImGui handle widget state without persistent objects?

ImGui stores all necessary UI state—including which item is hovered, active, or focused—in the global `ImGuiContext` structure defined in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp). When you call a widget function like `Button()`, the code checks this internal state to determine what to draw and return, without requiring you to allocate or manage any widget instances.

### Is ImGui's immediate mode suitable for complex user interfaces?

Yes, ImGui handles complex interfaces through composition of immediate calls, though it is optimized for tools, debuggers, and game engines rather than traditional desktop applications. Complex layouts use functions like `TreeNode()`, tables, and splitters from [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp), while the immediate nature ensures the UI always reflects current application state without manual synchronization.

### What graphics APIs does ImGui support?

ImGui is backend agnostic. The core library in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) generates platform-independent draw lists that any backend can consume. Official backends include [`imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_opengl3.cpp) for OpenGL 3+, [`imgui_impl_vulkan.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_vulkan.cpp) for Vulkan, and implementations for DirectX, Metal, and SDL, allowing integration with virtually any rendering pipeline.