Immediate Mode Rendering vs Retained Mode Rendering
The two opposing philosophies for drawing UI and graphics: redraw everything every frame from current state, or build a persistent object tree the framework diffs and re-renders for you. One wins for tools and games, the other for documents and apps.
The short answer
Retained Mode Rendering over Immediate Mode Rendering for most cases. For 95% of the interfaces anyone actually ships — forms, dashboards, documents, settings panels, mobile apps — retained mode is the correct default.
- Pick Immediate Mode Rendering if already run a per-frame render loop (a game, an editor, a profiler/debug overlay), your widget count is modest, and your UI is driven by data that changes every frame — Dear ImGui exists for exactly this and it's glorious there
- Pick Retained Mode Rendering if building basically any product UI: documents, forms, dashboards, mobile apps, websites. You want the framework to own layout, invalidation, accessibility, and event routing instead of you
- Also consider: They are not mutually exclusive in one app. Most shipping software is retained-mode at the app layer (React, the DOM, UIKit, Flutter) with immediate-mode islands for canvas, charts, or in-house dev tools. Knowing which mode a given surface wants is the actual skill.
— Nice Pick, opinionated tool recommendations
What they actually are
Immediate mode rendering means the UI has no persistent representation. Every frame, your code re-issues every draw and interaction call from current application state: if (Button("Save")) save(). The widget doesn't exist between frames — it's reconstructed each loop. Retained mode means you build a persistent tree of objects (a DOM, a scene graph, a widget hierarchy), mutate it, and the framework figures out what changed and redraws only that. The DOM, UIKit, Qt Widgets, and Flutter are retained. Dear ImGui and most game-engine debug UIs are immediate. The dividing line isn't 'old vs new' — it's who owns state. In immediate mode YOU own all UI state and the renderer is dumb. In retained mode the FRAMEWORK owns the object graph and you mutate it. Everything else — performance, ergonomics, accessibility — falls out of that one decision. Get the ownership model right and the rest is detail.
Performance and where each wins
Immediate mode's reputation as 'fast' is half-true and people quote it badly. It's fast to write and fast for small, hyper-dynamic UIs because there's no diffing, no allocation churn, no reconciliation — you just draw. But it redraws everything every frame whether or not anything changed, which is wasteful for a static settings screen and murder on battery for a mobile app idling at 60fps. Retained mode pays an upfront cost — building and diffing a tree — but then only repaints dirty regions and can sit at zero CPU when nothing moves. For a 10,000-row table that updates one cell, retained mode wins decisively; immediate mode would re-emit all 10,000 rows per frame. For a profiler overlay with 40 widgets all changing every frame, immediate mode wins because the diffing overhead is pure tax. Match the mode to your invalidation pattern, not to a benchmark someone tweeted.
Developer ergonomics and the hidden costs
Immediate mode feels incredible at first: no callbacks, no state-binding ceremony, no separate model — the code reads top to bottom and the UI is just a function of your variables. For tools and prototypes this is a genuine joy and Dear ImGui earned its fans honestly. The bill comes later. You hand-manage focus, scroll position, animation state, and layout because there's no persistent node to hang them on. Accessibility is brutal — screen readers expect a queryable tree, and immediate mode doesn't have one, so native a11y is effectively off the table. Retained mode front-loads the ceremony (components, props, reconciliation, lifecycle) but gives you accessibility, devtools that inspect a real tree, declarative layout engines, and a mature ecosystem. Immediate mode is a sharp knife for a known cut. Retained mode is the kitchen. Ship products in the kitchen.
The decisive read
Stop framing this as a rivalry — it's a layering decision, and the people who treat it as religion ship worse software. The honest rule: retained mode is your default because the things humans use all day (documents, forms, apps, the entire web) are mostly static between interactions and need accessibility, and the framework earning its keep on layout and invalidation is worth the ceremony. Reach for immediate mode only when you can point at the frame loop you already live inside and your UI genuinely changes every frame. That's game tooling, editors, profilers, debug HUDs — real, valuable, and narrow. The pros who use immediate mode well do it as islands inside a retained app: a canvas chart, an in-engine inspector, a node graph. If you can't name your render loop, you don't have one, and you should be in retained mode. Pick retained, carve out immediate where it's earned.
Quick Comparison
| Factor | Immediate Mode Rendering | Retained Mode Rendering |
|---|---|---|
| Who owns UI state | You do — widgets are reconstructed every frame, no persistent objects | The framework does — a persistent object tree you mutate |
| Idle / static-screen cost | Redraws everything every frame even when nothing changes — battery tax | Repaints only dirty regions, can sit at zero CPU |
| Hyper-dynamic UI inside a render loop | No diffing overhead — ideal for per-frame-changing tools and HUDs | Reconciliation overhead is pure tax when everything changes anyway |
| Accessibility | No queryable tree — native screen-reader support is effectively off the table | Persistent tree maps to accessibility APIs out of the box |
| Default fit for product UIs | Niche: games, editors, profilers, debug overlays | Documents, forms, dashboards, mobile, web — the 95% case |
The Verdict
Use Immediate Mode Rendering if: You already run a per-frame render loop (a game, an editor, a profiler/debug overlay), your widget count is modest, and your UI is driven by data that changes every frame — Dear ImGui exists for exactly this and it's glorious there.
Use Retained Mode Rendering if: You're building basically any product UI: documents, forms, dashboards, mobile apps, websites. You want the framework to own layout, invalidation, accessibility, and event routing instead of you.
Consider: They are not mutually exclusive in one app. Most shipping software is retained-mode at the app layer (React, the DOM, UIKit, Flutter) with immediate-mode islands for canvas, charts, or in-house dev tools. Knowing which mode a given surface wants is the actual skill.
Immediate Mode Rendering vs Retained Mode Rendering: FAQ
Is Immediate Mode Rendering or Retained Mode Rendering better?
Retained Mode Rendering is the Nice Pick. For 95% of the interfaces anyone actually ships — forms, dashboards, documents, settings panels, mobile apps — retained mode is the correct default. The framework owns layout, invalidation, accessibility, and event routing so you don't hand-roll a scene graph and dirty-rect logic for the thousandth time. Immediate mode is the right call only when your UI count is tiny, your data is wildly dynamic, and you're already inside a per-frame render loop (game engines, debug tools, profilers). That's a real niche, not a default. Pick retained unless you can name the frame loop you're living in.
When should you use Immediate Mode Rendering?
You already run a per-frame render loop (a game, an editor, a profiler/debug overlay), your widget count is modest, and your UI is driven by data that changes every frame — Dear ImGui exists for exactly this and it's glorious there.
When should you use Retained Mode Rendering?
You're building basically any product UI: documents, forms, dashboards, mobile apps, websites. You want the framework to own layout, invalidation, accessibility, and event routing instead of you.
What's the main difference between Immediate Mode Rendering and Retained Mode Rendering?
The two opposing philosophies for drawing UI and graphics: redraw everything every frame from current state, or build a persistent object tree the framework diffs and re-renders for you. One wins for tools and games, the other for documents and apps.
How do Immediate Mode Rendering and Retained Mode Rendering compare on who owns ui state?
Immediate Mode Rendering: You do — widgets are reconstructed every frame, no persistent objects. Retained Mode Rendering: The framework does — a persistent object tree you mutate.
Are there alternatives to consider beyond Immediate Mode Rendering and Retained Mode Rendering?
They are not mutually exclusive in one app. Most shipping software is retained-mode at the app layer (React, the DOM, UIKit, Flutter) with immediate-mode islands for canvas, charts, or in-house dev tools. Knowing which mode a given surface wants is the actual skill.
For 95% of the interfaces anyone actually ships — forms, dashboards, documents, settings panels, mobile apps — retained mode is the correct default. The framework owns layout, invalidation, accessibility, and event routing so you don't hand-roll a scene graph and dirty-rect logic for the thousandth time. Immediate mode is the right call only when your UI count is tiny, your data is wildly dynamic, and you're already inside a per-frame render loop (game engines, debug tools, profilers). That's a real niche, not a default. Pick retained unless you can name the frame loop you're living in.
Related Comparisons
Disagree? nice@nicepick.dev