SwiftUI
SwiftUI Architecture Is Mostly State Ownership
Why production SwiftUI architecture is less about folder names and more about ownership, identity, effects and boundaries.
5 min read
The architecture debate starts too late
Many SwiftUI architecture debates start with the wrong question: should we use MVVM, TCA, Clean Architecture or something custom? That question matters, but it is not the first question.
The first question is: who owns the state? Most SwiftUI problems that feel architectural are really ownership problems. A value changes in one place, the screen updates somewhere else, an effect returns late, identity changes unexpectedly, and the team starts blaming SwiftUI.
SwiftUI is not forgiving when ownership is vague. It will render exactly what your model says, even if your model has no clear source of truth.
A screen has several kinds of state
A production screen usually has more than one kind of state. There is server state, local persisted state, in-memory view state, form state, navigation state, loading state, optimistic state and derived state.
If those are all pushed into one view model without names, the model becomes a drawer for everything the screen might need. That is not architecture. It is storage.
A stronger design names the state and decides which layer owns each piece. The view can own short-lived presentation state. A model can own screen behavior. A repository can own persistence and remote refresh. A coordinator or router can own navigation. The exact names matter less than the ownership being explicit.
Identity is not a cosmetic detail
SwiftUI identity decides whether state is preserved, reset or duplicated. A list row, tab, sheet or navigation destination can behave strangely when identity changes without the team noticing.
This is why production SwiftUI architecture needs rules for IDs, lifetime and view creation. If a view creates an object, it owns that object's lifetime. If it receives an object, ownership lives somewhere else. If a task is tied to view identity, it may restart when identity changes.
The senior answer is not just which property wrapper to use. The senior answer explains what lifetime the property wrapper represents.
Effects need ownership too
Networking, search, image loading, analytics, persistence and sync are effects. If the effect belongs to what the user currently sees, it can often be tied to view lifetime. If the effect represents user intent or data integrity, it needs a more durable owner.
A search request can be cancelled when the query changes. A draft save should not disappear because the view navigated away. A payment confirmation should not depend on a transient view still existing.
Good SwiftUI architecture separates visual work from user-intent work. That distinction prevents many bugs that otherwise look like random async behavior.
The useful architecture question
When reviewing a SwiftUI architecture, ask this: if the app is backgrounded, the network returns late, the user navigates away, the same screen appears twice and cached data refreshes underneath it, does the state model still make sense?
If the answer is no, changing the pattern name will not save the feature. The ownership model has to become clearer.
SwiftUI rewards small, honest boundaries. Not because small files are magic, but because clear ownership makes rendering, testing and failure recovery easier to reason about.
Where this fits
This essay belongs to the Design Systems path: Offline-first sync, caching, modularization, persistence, performance, platform strategy and architecture governance.