Concepts•Jun 2026•3 min read

Immediate Mode vs Retained Mode Rendering: The Decisive Verdict

Two opposing philosophies for drawing UI. One redraws everything every frame and owns no state. The other builds a persistent object tree and mutates it. Here's which one to reach for, and when the other earns its keep.

The short answer

Retained Mode Rendering over Immediate Mode for most cases. Retained mode wins because most software is not a 144fps game loop — it's forms, lists, documents, and accessibility trees that change rarely and must be.

  • Pick Immediate Mode if building a game, a debug overlay, a tool inside an engine, or any UI that already redraws every frame and whose state lives elsewhere — Dear ImGui-style code is the fastest path from intent to pixels
  • Pick Retained Mode Rendering The Decisive Verdict if building application UI: documents, forms, data tables, anything with accessibility, deep widget trees, or content that's static most of the time. The persistent tree pays for itself
  • Also consider: Modern hybrids (React, Flutter, SwiftUI) give you an immediate-mode authoring feel over a retained-mode engine — you describe UI declaratively each render, a diff/reconciler keeps a real tree underneath. That's usually the actual right answer in 2026.

— Nice Pick, opinionated tool recommendations

What the two actually are

Immediate mode rendering means your code issues draw commands every frame and the system retains nothing between frames — there is no button object, just a Button("OK") call that draws and returns whether it was clicked this frame. Dear ImGui, Nuklear, and most game-engine debug UIs work this way. Retained mode means you construct a persistent tree of objects — the DOM, a scene graph, Qt's widget tree, a display list — and the framework walks that tree to render, redrawing only what changed. The core distinction is ownership of state: immediate mode pushes UI state out to your application; retained mode holds it inside the tree. Everything else — performance characteristics, accessibility, hit-testing, animation — flows from that single decision about who remembers what was on screen last frame.

Where immediate mode genuinely wins

If you already run a render loop at 60–144fps, immediate mode is gloriously direct. No state to sync, no "the model and the view disagree" bugs, no observer boilerplate — the UI is a pure function of your app state, recomputed each frame. That makes it unbeatable for game tools, level editors, profilers, and debug overlays, where ImGui can stand up a panel in five lines that would be fifty in a widget toolkit. Code reads top-to-bottom and maps one-to-one to what's on screen. The cost is honest: you pay full CPU/GPU to redraw a static screen, text input and complex layout are awkward, and accessibility is essentially nonexistent. Nobody ships a screen-reader-friendly tax form in Dear ImGui. For ephemeral developer-facing UI, none of that matters and the velocity is real.

Where retained mode earns the default

Application UI is mostly idle. A settings page, a spreadsheet, a chat log — they change on interaction, not on a clock. Retained mode exploits this: it only re-renders dirty regions, so a static window costs near-zero. More importantly, the persistent tree is the substrate every serious UI feature needs. Accessibility APIs read the tree. Hit-testing walks the tree. Layout engines, focus management, animation interpolation, CSS-style cascading — all assume a queryable, stable object graph. Immediate mode has to reconstruct each of these manually because it deliberately threw the tree away. Yes, you pay in complexity: state synchronization, invalidation bugs, and the eternal "why didn't my widget update" debugging. But that complexity buys inspectability and efficiency at rest, which is exactly what shipped products require. The DOM is retained mode, and the entire web runs on it for a reason.

The hybrid most people should actually use

The honest 2026 answer is that you rarely pick pure either. React, SwiftUI, Flutter, and Jetpack Compose hand you immediate-mode ergonomics — you re-describe your whole UI declaratively on every render, as if redrawing each frame — while a reconciler diffs your description against a retained tree and mutates only the deltas. You get the "UI is a function of state" clarity without paying to literally repaint static pixels, and you keep accessibility and hit-testing because a real tree still exists underneath. This is why the immediate-vs-retained debate often feels stale: the winning architecture stole the good half of each. If you're choosing a paradigm for new app UI, don't agonize over the binary — reach for a declarative retained-backed framework. Choose raw immediate mode only when you're inside an engine loop, and raw retained mode only when you need maximal control over the tree itself.

Quick Comparison

FactorImmediate ModeRetained Mode Rendering The Decisive Verdict
Cost when the screen is staticFull redraw every frame regardless of changesNear-zero — only dirty regions repaint
Authoring velocity for ephemeral/dev UIExcellent — five lines, no state syncVerbose — construct and wire up objects
Accessibility & hit-testingMust be built by hand; usually absentFree from the persistent queryable tree
State synchronization bugsNone — UI is pure function of app stateModel/view drift, invalidation bugs common
Fit for shipped application UIPoor — text input, layout, a11y all painfulThe substrate every serious UI feature needs

The Verdict

Use Immediate Mode if: You're building a game, a debug overlay, a tool inside an engine, or any UI that already redraws every frame and whose state lives elsewhere — Dear ImGui-style code is the fastest path from intent to pixels.

Use Retained Mode Rendering The Decisive Verdict if: You're building application UI: documents, forms, data tables, anything with accessibility, deep widget trees, or content that's static most of the time. The persistent tree pays for itself.

Consider: Modern hybrids (React, Flutter, SwiftUI) give you an immediate-mode authoring feel over a retained-mode engine — you describe UI declaratively each render, a diff/reconciler keeps a real tree underneath. That's usually the actual right answer in 2026.

🧊
The Bottom Line
Retained Mode Rendering wins

Retained mode wins because most software is not a 144fps game loop — it's forms, lists, documents, and accessibility trees that change rarely and must be inspectable. Retained mode gives you scene graphs, dirty-region invalidation, hit-testing, and a11y for free, which immediate mode forces you to rebuild by hand. Immediate mode is the specialist's tool; retained mode is the default that scales to real product UI.

Related Comparisons

Disagree? nice@nicepick.dev