SwiftUI has been production-viable for years now. The interesting question is no longer whether to use it, but where UIKit still earns its place in a codebase that is otherwise declarative.
Where SwiftUI is now the default
New screens, new apps, and anything that needs to exist on more than one Apple platform. The multi-platform argument is the strongest one: the same view code runs on iPhone, iPad, Watch and Mac, which is what makes shipping the second platform a fraction of the cost of the first.
Where UIKit still wins
- Deeply custom collection and scroll behaviour
- Fine-grained control over transitions and interruptible animation
- Text engines, complex input handling, and long-lived legacy screens
Mixing them without regret
UIViewRepresentable and UIHostingController make interop cheap in both
directions. The rule that keeps it maintainable: pick one paradigm per screen,
never per component. Screens that are half declarative and half imperative are
where the state bugs live.
Migration strategy for an existing app
Migrate screen by screen alongside feature work rather than as a rewrite. The data layer moves first, the leaf screens second, navigation last — navigation is the part that hurts, so do it once you have practice.
Where this comes up
Most of our iOS work is SwiftUI-first, and most app rescue engagements involve a UIKit codebase that needs a migration path rather than a rebuild.