SwiftUI After 7 Years
https://ykvm.com/2026/07/swiftui-a-story-of-mediocrity/Apple's inability to deploy a new UI framework that's better than the previous one is troubling. This is the company that shifted from Toolbox to Carbon to Cocoa and each step was better than the last. Could Apple build MacOS X and Cocoa today if they didn't already exist? Microsoft's two decades of failure to ship a true successor to Win32 suggests that Microsoft (at least, the operating system side of the company) died a long time ago. I wonder if we'll say the same thing about Apple 10 years hence.
Data Flow: The author claims there’s no way to know when things update. Not only does experience help here but there are profile tools that tell you when and where things are updated. This isn’t black magic. Keep Views small, be careful how you hand around data. @environment is super cool but can have a cascade effect. This was greatly improved iOS 17+ and I wouldn’t support anything older than iOS 17.
GeometryReader: Occasionally I’ll use this. It’s kind of a necessary evil when dealing with certain view complexity. It can also be a sign that you’re doing something wrong.
API Stability and performance: Apple users upgrade. There’s no reason that you should be supporting iOS 17 at this point — even iOS 18 is roughly 2%% of our user base across several apps. I’ve been using SwiftUI without major performance issues but I also don’t early optimize. I profile and fix as needed. One of the early studios I worked for wrote all our games in UIKit as prototypes, when performance tanked we’d switch to the appropriate tools (eg. OpenGL) where it was necessary — like in the core game.
I could go on but in the end just use the right tool for the job, if you’re not proficient in SwiftUI or it isn’t going to work for your cross platform project, you have a lot of other alternatives. For me though, it’s been amazing to work with. I stepped away from iOS programming for 3 - 4 years because I was burnt out using storyboards, dealing with massive view controllers, and all the boiler plate it’d take to get a view up and going in UIKit. SwiftUI roped me back in.
* Quick addition edit: Cross platform for iOS, iPad, macOS has never been good. I’ve found recent updates have made things better to the point of tolerable and it’s nothing like when we had to post-fix an ~ipad to our Nibs — There has never been a ‘glory days’ of cross platform Apple UI libraries.
After two many trial and fail, now it's quite clear to me that for simple UI I will use swiftUI(such as help sheet or simple toggles), for complex and performance first, I will just use UIKit instead, it save a log of time and actually the imperative UIKit is also quite easy to read and review
the feasibility of review is important because code is not mainly written by agent, though as my understanding of UIKit grows I can smell the bad part and let it rewrite
These frameworks have a number of good ideas but they don't necessarily combine in a way that transcends high quality traditional imperative frameworks with declarative-reactive bits sprinkled throughout, at least for more complex apps. SwiftUI and its ilk work best for super simple tabs-and-flat-lists sorts of apps.
Just MHO, and it’s not going to stop the juggernaut, but there’s just no appeal in moving there for me :( If (when ?) Apple drop ObjC, that’s the day I move to Linux
For my app which is a AI chat app, I needed to load and show a large number of chat items in a list, SwiftUI is really bad at this. Another issue is, most of Swift markdown libraries don't perform perform well because each elements are rendered as SwiftUI views which introduced a lot of issues So I built my own renderer using TextKit. Even basic things like Settings window is broken. But I still prefer using SwiftUI as It gets the work done faster and I can always fallback to AppKit.
I find that web tech like React are worst than SwiftUI. React also has re-rendering and state management issues
The boundaries aren’t perfectly clean, and that’s fine. But the separation gives you a useful way to think: structure this first, style it later, add behaviour where needed.
My experience with Compose—though I suspect SwiftUI people will recognise the feeling—is that I have to think about everything, everywhere, all the time.
Then we add some MVVM/UDF flavour. The "ViewModel" knows nothing about the view, despite usually serving exactly one screen. Add some "MutableStateFlow"s, combine them into "ScreenUiState", expose it as a "StateFlow", collect it with lifecycle awareness.
Beautifully decoupled. Extremely testable.
Then the organisation writes no unit tests and relies entirely on two-hour nightly screen tests.
A welcome-page refactor breaks the profile page.
“Didn’t you check the nightly build?”
No. It runs at night.
“Well, that’s your responsibility.”
But you broke it.
“Yes, but it’s your code.”
Then why did we ship it?
Fine. Schedule the postmortem with my mother.
And I’m not blaming mobile developers here. I’m frontend, backend, full-stack, I think AI engineer now. I have personally helped make simple things complicated across the entire stack.
What I like about the web is that one simple screen can be vanilla JavaScript. Another can use Vue. Another can use some specialised spreadsheet component.
People react to that with horror: what if components are duplicated, behave or look slightly different?
Fair concern. But that is real coupling with visible consequences and trade-offs. Somehow we have started treating coupling as something abstract that only exists inside code, rather than something that should produce an actual benefit when removed.
HTML. CSS. JavaScript. Or something close to it.
Maybe I’m getting old.
On macOS it is still comes up short on a lot of the GUI functionality. Stuff like window management, decoration, focus, undo/redo, finder tree type views etc. What Apple have implemented seems okay to me for iPad, iOS etc, but is not up to the standards users' expect for non-trivial native desktop applications.
With enough determination most of the omissions on macOS can be worked around by breaking the SwiftUI encapsulation and delving into AppKit or jarringly inelegant solutions. All of which are somewhat liable to ended up binned when/if Apple pull their fingers out. I had higher expectations of Apple, and overall, it's easy to understand why it does not have a stellar reputation.
As to why it's a bit rubbish on macOS; SwiftUI is largely a mapping to UIKit, AppKit etc primitives. At a guess Apple wants to reduce that number and are seeking to minimise investment in moribund technology.
NavigationStack has been around since iOS 16, @Observable since iOS 17. and I'm not sure if the author is aware that GeometryReader hasn't been necessary since iOS 18 added onGeometryChange modifiers. Nearly 100% of users are on iOS 16+.
I'm doing some fairly complex work with SwiftUI and I find most components work identically between iPad and macOS. I can work for a week without needing to test on an iPad.
There are problems with SwiftUI for sure: I'm finding macOS performance on an M2 Max is far worse than an iPad M1, especially with animations. Toolbars are very inconsistent between platforms and the compiler timeouts are a real pain (hopefully Swift 6.4 will fix that).
SwiftUI is a laudable attempt to idiot-proof UI, but it sacrifices too much and ultimately fails.
What does this even mean? There are hundreds of thousands of apps in the App Store that are 100% SwiftUI. They are real. And they are very much "production grade".
The only people still complaining about SwiftUI 7 years later are the UIKit holdouts that never took the time to properly learn how to use it.
It is a newbie trap. It is great at producing simple apps, or things that don't require intense scrolling, or anything with heavy animations and precise layouts, but when you do something smooth, it is not it. It feels more of a React Native competitor, than a true UIKit replacement.
Also, almost everything that Apple has re-wrote with SwiftUI, came out worse as before (Settings, Spotlight, etc), and that doesn't help.
With AI coding... SwiftUI lost its edge/advantage (easy to layout screens), as now you code less of that directly, and might as well just go fo the framework that allows the most flexibility and gives you the best results for your users.
Apple really needs to either double down on it, and make it such that it has everything that UIKit has (match both features and performance), or just turn it into another optional framework, just as Interface Builder (.xib files) back in the day of Objective-C.
Right now it heavily promotes it as a first class citizen, meanwhile the features are not even parity with UIKit. It is so misleading to newcomers to the platform.
Ps. The other upsetting thing about SwiftUI, is that it has hurt the Swift language as well, as the team has had to introduce all kinds of hacks, or obscure features to the language in order to make it work, which made even the Swift language experience worse and more complicated than it should have been.
I can render Metal shaders trivially in SwiftUI. Rendering glows, and blurs, and animated effects is much easier in SwiftUI than in UIKit, just use `.blur(radius:)` or `.blendMode(...)`
I have used AppKit and then UIKit since its inception. Creating visual effects like layer masks that modulate the opacity of underlying views is trivially easy in SwiftUI — far easier than the boilerplate and constant bookkeeping that CALayer's mask requires.
So a lot of the advanced full-screen animations in some of my games and apps are SwiftUI, because they are performant, provide the cool effects and animations, and work great. A lot of the simple get-the-job-done views and tool palettes in my apps are also SwiftUI, again because they don't ask much and get the job done, and look great.
However, where SwiftUI falls down is exactly what was demoed in the video: large collections of thumbnails that fetch asynchronously? Use UIKit. Multi-thousands of items in large, complicated lists? You can try SwiftUI, but you'll need to learn how to optimize it.
Other things, not mentioned in the video, that are more annoying in SwiftUI: want to take control of a transition between views, end-to-end? Not really possible in SwiftUI. There are bugs with ZoomNavigationTransition that affect all of Apple's own apps, and you aren't gonna be able to fix them without switching to UIKit.
I went through Visual Basic, .NET, WPF, Cocoa, and other random frameworks all professing to be the promised panacea for UI, but I think SwiftUI+SwiftData is the best environment ever.. IF only it could reach its full potential, i.e. do everything that Apple's "legacy" APIs can do.
I even tried using SwiftUI for games: https://i.imgur.com/5aTWbft.mp4
The biggest/worst hurdle in the "modern" dev experience is Apple's insistence on a yearly update cycle and the way they advertise those updates: You have to wait for the next WWDC and suffer through videos of uncanny-valley presenters, hoping to catch a glimpse of something that fixes the shit that was bothering you since the last WWDC.
3rd-party sites like hackingwithswift.com & swiftwithmajid.com provide invaluable info that Apple's own docs should.
At least the Swift language has been getting more regular updates since it went open source.
There's no way I'd dare to take on a full Apple-platform app project alone on my own, but I've started dabbling in it again thanks to AI: Codex even converted an old app I made in Visual Basic 900 years ago and had it running in SwiftUI within minutes!
I've even tried to get AI to sift through the WWDC video transcripts so I won't have to waste my mortal lifespan on that.
1. It uses the builder pattern for views (familiar to those who used Java) but for some reason they decided to make it so that the order of the modifiers in the builder matters. Each modifier doesn't actually modify the main view but it modifies what the modifier before it decided to return. This makes no sense as the modifiers should each be modifying the main view to make everything predictable and easy to debug. I'm convinced no one (not even senior devs with 5 years of SwiftUI experience) understands how the ordering of modifiers works. It's just swap them until it does what you want it to.
2. The view lifecycles and code execution path seem random and hidden behind layers of "magic," making it incredibly difficult for developers to trace and debug issues.
3. It is practically impossible to set breakpoints for rendering and view construction, it's impossible to really figure out when re-renders happen and what drives them. I'm convinced SwiftUI apps are incredibly slow not because the SwiftUI implementation itself is slow, it's because, even Apple's own apps probably do a bunch of unnecessary re-renders and one no one seems to have any idea. This is unfortunately another design issue that can't be solved by just making SwiftUI more efficient. It requires simplification and tooling to help developers not footgun themselves.
4. Lots of issues start appearing later on in the development cycle because, for simple apps, bad SwiftUI design decisions and footguns have unnoticeable effects, until the apps gets more complex and things start breaking. Fixing these issues sometimes requires rewriting whole features or spending hours debugging.
5. There seems to be almost no documentation on Liquid Glass. It's laughable that after more than 1 year, Apple has simply refused to document or provide good examples for Liquid Glass, except for maybe couple pages that resemble the brain dump of an engineer that has never passed a writing class in college?
6. Stuff seems to be rapidly changing and breaking from version to version. It took days to make my app look and work the same in iOS 27 as it did on iOS 26, even though iOS 27 is supposed to be a minor bug fix release. We don't even use anything non-standard and don't do any hacks. This defeats the whole purpose of a simple UI framework that can be easily adopted to different platforms (this never used to happen with UIKit).
7. View debugger still has no SwiftUI equivalent. It used to make things so much simpler in UIKit when you could just see the view bounds, pick views apart and understand what's actually happening. SwiftUI has no equivalent other than `.background(.red)`. Terrible.
I don't know how Apple can salvage this beyond just undoing some of these terrible design decisions and making it 1. super simple to work with, 2. stop relying on magic, making things more explicit, and 3. providing actual 1:1 UIKit feature parity.
Swift feels impenetrable. So much syntax and features that are “progressively disclosed” (horrible UX paradigm btw) but instead just jump at you, breaking threading semantics, and horrible tooling. It’s also the only language I cant* get AI to perform decently well at, a double con.
I hate swift so much.
But now I feel like for most apps, I should be fine with Compose Multiplatform and Kotlin Multiplatform. I don't see the point of learning SwiftUI anymore.
But is there a single UI abstraction that succeeded in affordability for newcomers while maintaining performance and solid architecture?
It is high time to solve the write-3-apps for each usecase (iOS, Android, Windows). I use MAUI on some projects but it is still not perfect.
The way forward for Apple is to open source more and more and let the Swift community build a cross-platform solution.