SwiftUI After Five Years: What Works and What Doesn't
SwiftUI launched in 2019 with a demonstration that made experienced iOS developers simultaneously excited and nervous. Excited because the declarative paradigm promised to eliminate the impedance mismatch between interface builder storyboards and code. Nervous because Apple’s track record with new frameworks included several that were replaced, deprecated, or quietly ignored within a few development cycles.
Five years later, SwiftUI is neither the complete replacement for UIKit that Apple’s marketing implied nor the abandoned experiment that skeptics predicted. It is a mature but still-evolving framework that handles a large majority of common iOS UI requirements elegantly, struggles with a specific set of advanced requirements, and has permanently changed how iOS UI code is written even when developers reach for UIKit to solve problems SwiftUI cannot.
Where SwiftUI Delivered
The declarative model’s productivity advantages for standard UI patterns are real and significant. A list view with custom cells, navigation, and data binding that required substantial boilerplate in UIKit — delegates, data sources, cell registration, dequeue patterns — is concise and readable in SwiftUI. The preview system allows designers and developers to iterate on UI without building and running the full app. The data flow model — @State, @Binding, @ObservableObject, and the newer @Observable macro — provides a principled approach to managing UI state that the UIKit model left largely to each team’s conventions.
SwiftUI’s layout system — the combination of stacks, spacers, frames, and the geometry reader — is expressive enough for most layouts and considerably less verbose than Auto Layout constraint code. For developers new to iOS development, SwiftUI is a dramatically more accessible starting point than UIKit was. For experienced UIKit developers, the learning curve is conceptual rather than syntactic — the declarative thinking required differs meaningfully from the imperative UIKit approach.
Where SwiftUI Still Struggles
The gaps in SwiftUI’s coverage become apparent when building applications that push beyond standard patterns. Complex custom animations that require fine-grained control over timing and interpolation frequently require dropping into UIKit or using third-party animation libraries. Custom gesture recognizers that interact with SwiftUI’s gesture system can produce unexpected behavior that requires careful handling. Certain UIKit components — UICollectionView with complex layouts, WKWebView, MKMapView — require the UIViewRepresentable wrapper, which is functional but brings UIKit’s imperative patterns back into the SwiftUI component tree.
The minimum deployment target requirement is the most practically limiting constraint. SwiftUI features are frequently tied to specific iOS versions. Developers who need to support iOS 15 — still used by a meaningful percentage of active devices — cannot use SwiftUI features introduced in iOS 16 or 17 without conditional compilation or feature detection code that partially defeats the framework’s expressiveness advantage.
Apple’s annual WWDC releases have consistently added new SwiftUI capabilities, but the pattern of releasing features that require current or near-current iOS versions means that the feature set available for production apps targeting broad device compatibility lags the feature set available in Apple’s own app previews by two to three years.
The UIKit Relationship
The relationship between SwiftUI and UIKit has settled into productive coexistence rather than replacement. New iOS projects start in SwiftUI and reach for UIKit when SwiftUI cannot do what is needed. Large existing UIKit codebases adopt SwiftUI incrementally, using UIHostingController to embed SwiftUI views within UIKit hierarchies and UIViewRepresentable to embed UIKit components within SwiftUI trees.
Apple’s documentation and sample code has increasingly reflected this hybrid approach, which is an implicit acknowledgment that SwiftUI’s coverage, while broad, is not complete and is unlikely to be complete in the near term. The team at Apple building SwiftUI clearly intends it to eventually encompass everything that UIKit can do. The timeline for that completion remains undefined.
For developers starting new projects today, SwiftUI is the right default. For developers maintaining large UIKit codebases, a selective adoption strategy — SwiftUI for new screens, UIKit for existing screens that work, UIKit for the cases where SwiftUI falls short — is the pragmatic approach that the framework’s current state supports. The framework has delivered on its core promise. The complete replacement of UIKit is a longer project than five years has produced.