A SwiftTUI frame is not "draw the view." It is a short chain of typed,
immutable products produced under a deliberate scheduling and isolation
model. This page follows one small view through that chain, explains why
the engine is shaped the way it is, and points at the exact source that
implements each step. It is written for engineers reading the framework
for the first time, and as a refresher for people changing the renderer.
Two pipelines, one frame
A 7-product data model and a 5-stage scheduling model that are intentionally not the same shape.
Source-grounded
Every claim links to a file and line in swift-tui; nothing here is invented.
Current at HEAD
Mirrors the framework's own DocC Runtime Render Pipeline article.
01
The mental model: two views of one frame
The most common point of confusion is that SwiftTUI documentation
talks about seven phases in some places and five
stages in others. These are two descriptions of the same frame,
kept separate on purpose.
Phase products — the data model
Phase products are the values the engine computes, in order. Each is an
immutable type owned by SwiftTUICore. Later products are
derived from earlier ones; nothing earlier is mutated.
You can reason about correctness purely in these terms: given a resolved
tree, layout is a function; given placement, drawing is a function.
Runtime stages — the scheduling model
Runtime stages are the boundaries an interactive session schedules work
across. They are owned by SwiftTUIRuntime and exist to place
cancellation points, animation sampling, and an off-actor boundary.
head → animationInjection → latePreferenceReconciliation → fusedFrameTail → commit
fusedFrameTail deliberately collapses five phase products
into one scheduling node so that pure work can leave the main actor.
The mapping is not one-to-one. head covers
resolve; animationInjection and
latePreferenceReconciliation adjust the in-flight draft
without introducing a new product; fusedFrameTail spans
measure→raster; commit covers
commit. That difference is the whole point of having two
models — see isolation.
02
Walk a frame through the runtime stages
Step through the five runtime stages. The left panel highlights the
authored lines being interpreted, the center describes the stage, and the
right panel shows the products that exist so far — honestly: no
terminal cells exist until raster inside the fused tail.
Authored input
BuildSummary.swift
View body
Runtime stage
RuntimeRenderPipeline
1 / 5
Products so far
Frame state
building head
03
The seven phase products
Each product answers one question about the frame and is gathered, in
full, onto FrameArtifacts. Hosts consume committed contracts
rather than reaching into renderer-private state.
State writes, input, signals, and deadlines never call the renderer
directly. They record intent. A scheduler coalesces that intent,
and the run loop pulls one frame's worth of work at a time — which is why
ten mutations in a tick render once, not ten times.
05
What runs where
Authored View, Scene, and App values
are main-actor APIs. The fused tail is pure over already-resolved products,
so it can run off the main actor when the strategy allows. That boundary is
the reason the scheduling model exists at all.
Invariants the renderer upholds
06
Four fates of a frame
Computing a frame's products is not the same as showing it. Commit applies
completed-frame policy, and a candidate can take one of four paths. This is
the honest answer to "I changed state but nothing on screen changed."
Commit produces data, not output. RunLoop presents a committed
frame according to the configured output mode and the roles the surface
implements. Terminal bytes live entirely below this boundary.
The walkthrough above is grounded in these excerpts. Use the tabs to inspect
the points where data changes shape. Highlighted lines are the ones the prose
refers to.
09
Observing the pipeline
You do not have to read the source to see what the renderer did. With a
diagnostics sink installed, the runtime emits a RuntimeFrameSample
per committed frame, zero-artifact outcome, and elision.
SwiftTUIProfiling turns these neutral samples into consumer-facing
records and summaries; the runtime does not depend on the profiling product.
10
Where to look next
Start from the question you actually have. These are the framework's own
entry points, plus a glossary of the types named throughout this page.