Should an existing UIKit app migrate to SwiftUI?

How to decide whether, where and how to introduce SwiftUI into a production UIKit app without forcing a rewrite you cannot justify.

Usually, do not rewrite a healthy UIKit app solely to use SwiftUI. Introduce SwiftUI where it improves delivery or product quality, and use UIKit interoperability to migrate at feature or component boundaries. A full rewrite needs a product and risk case, not only a framework preference.

UIKit is not deprecated. It is actively maintained, it underpins an enormous amount of shipping software, and Apple continues to develop it. A stable UIKit screen that works, that nobody needs to change, and that no user complains about is not a problem waiting to be solved. It is just a screen.

That said, “do not rewrite” is not the same as “do nothing”. Most production UIKit apps should be introducing SwiftUI somewhere. The question is where, and in what order.

What SwiftUI genuinely improves

When SwiftUI is a good fit, the benefits are real and worth having.

Iteration speed on UI-heavy work. Declarative layout with previews shortens the loop between an idea and seeing it on screen, particularly for screens that are largely composition and state.

State-driven UI. A view that is a function of its state removes an entire category of bug: the screen that is correct on first load and wrong after the fourth navigation. UIKit can be written this way, but SwiftUI makes it the default rather than a discipline.

Design system components. Shared, composable components are considerably less ceremony in SwiftUI, which matters when several squads consume the same design library.

Platform features that arrive SwiftUI-first. Widgets, Live Activities and several newer surfaces are SwiftUI-only or SwiftUI-first. If the product roadmap includes them, you need SwiftUI competence regardless of what happens to your existing screens.

Recruitment and familiarity. Engineers joining now are more likely to have recent SwiftUI experience than deep UIKit experience. That is a genuine consideration, though a weak one on its own.

Where UIKit remains the right answer

Equally, there are places where moving is simply not worth it.

Stable screens nobody is changing carry migration risk with no offsetting benefit. Highly specialised behaviour, such as complex gesture handling, custom transitions, unusual collection layouts and heavy text or media work, is often still more predictable in UIKit, where the control surface is wider. Mature infrastructure that works, such as a battle-tested navigation coordinator, has a great deal of accumulated bug-fixing baked in that a replacement will not have. And anywhere the business has no reason to change is a place where the safest architecture decision is to leave it alone.

The factors that actually decide it

Work through these honestly. The answers vary enormously between products, which is why generic advice on this question is worth so little.

Minimum deployment target. SwiftUI’s capability, and the amount of workaround code you need, differs sharply by OS version. What share of your users would a raised minimum actually affect, according to your own analytics?

Team knowledge. Do your engineers have production SwiftUI experience, or would this be learning on a live product? Neither is disqualifying, but they imply very different pilot sizes.

Navigation and state architecture. This is usually the hardest boundary. An app with a clean, centralised navigation layer can host SwiftUI screens comfortably. An app where navigation is scattered across view controllers will find the seams painful.

Design system. If a rebuild of the design system is happening anyway, that is the cheapest moment to adopt SwiftUI components, because you are paying the rebuild cost once rather than twice.

Testing. How do you currently protect UI behaviour, and does that approach survive the move?

Roadmap pressure. Migration competes with features for the same engineers. If the next two quarters are fully committed, a large migration is not a technical decision; it is a roadmap decision, and it belongs with whoever owns the roadmap.

Expected lifetime. An app with two years left does not justify the same investment as one expected to run for ten.

Migration patterns that work

Assuming you decide to introduce SwiftUI, these are the boundaries that tend to hold.

New features in SwiftUI. The lowest-risk starting point. A new feature has no existing behaviour to regress, and it gives the team real experience without endangering anything.

Leaf components first. A card, a row, an empty state, a form field. Wrap them with UIHostingController or embed them in existing UIKit hierarchies. Small, contained and easy to reverse.

Hosting controllers at screen boundaries. A whole screen in SwiftUI, presented by the existing UIKit navigation. The screen is SwiftUI internally; the app’s navigation stays where it is. This is usually the most productive middle ground.

UIKit wrapped for SwiftUI. UIViewRepresentable and UIViewControllerRepresentable let you keep a hard-won UIKit component inside a SwiftUI screen. Wrapping is not failure; it is the interoperability working as intended.

A deliberate shared state boundary. Decide explicitly how state crosses between the two worlds, and write it down. This is where dual-framework apps most often become confusing.

The risks worth naming

Dual-framework complexity. For the duration of the migration, every engineer needs both. Underestimating this is the most common planning error.

Inconsistent navigation and state. Two navigation models coexisting without a clear rule about which owns what produces bugs that are genuinely hard to reason about.

Performance assumptions. SwiftUI performance is good, but it fails differently from UIKit. Excessive view invalidation, expensive body computation and poorly scoped observation cause problems that a UIKit-trained instinct will not predict. Profile rather than assume.

Accessibility regressions. A carefully accessible UIKit screen rebuilt quickly in SwiftUI often loses labels, traits, ordering or Dynamic Type behaviour. Accessibility must be part of the migration’s definition of done, not a follow-up ticket.

Premature abstraction. Building an elaborate framework for migrating before you have migrated anything. Do one feature the plain way and learn what the abstraction should be.

Run a pilot before committing

The most useful thing you can do is stop debating and migrate one thing.

Choose a feature that is representative but bounded: real navigation, real state, real network calls, real accessibility requirements, but small enough that being wrong is cheap. Define what you will measure before you start: engineering days, defects found in review and in production, crash-free rate for that flow, and how the team felt about it. Ship it. Then write the pattern down: how state crosses the boundary, how navigation is handled, how it is tested.

At that point you have evidence instead of opinions, and you can decide whether to repeat it.

When a broader rewrite may be justified

It happens, but it should remain exceptional. A rewrite starts to make sense when the product itself is being replaced rather than evolved; when the existing architecture genuinely cannot support the roadmap and incremental change keeps failing; when foundations are abandoned or unsupportable, such as a discontinued third-party framework with no path forward; or when a full design rebuild is happening anyway, so the UI layer is being replaced regardless.

Note what is not on that list: the code being old, the code being UIKit, or the team preferring SwiftUI. Those are reasons to migrate incrementally, not reasons to start again.

If you are weighing this decision on a real product, my iOS Modernisation service is built around exactly this: choosing the boundaries, sequencing the work, and keeping the app releasable throughout. If you have inherited the codebase recently and are not yet sure what you are dealing with, it is usually worth assessing the codebase before making any framework decision at all.

Weighing up a SwiftUI migration?

Describe the app, the team and the roadmap pressure. I will give you a candid view on whether, where and how to introduce SwiftUI, and what it would cost you to get wrong.