SDUI vs WebViews on iOS
SDUI renders native SwiftUI from JSON. A WebView renders HTML in a browser process. Teams pick SDUI when the page should feel like the rest of the app.
SDUI vs WebViews on iOS is a renderer choice. SDUI, in the Flow-UI sense, renders native SwiftUI from JSON. A WebView renders HTML in a browser process. Pick SDUI when the page should feel like the rest of the app. Pick a WebView when the page is a document or a vendor web flow.
Kenin Kujovic and others sketch three options: WebView, shared cross-platform code, and SDUI. This post is the first pair. Cross-platform code waits for a later article. There are no FPS numbers here. Feel and operations are the comparison.
What each renderer owns#
A WebView owns CSS layout, a DOM, JavaScript, and web navigation. You get the entire web platform, including the bugs of the entire web platform. You also get your existing web CMS.
SDUI owns a JSON schema and a catalogue of native widgets. You get platform scrolling, gestures, and accessibility. You do not get <div> soup. New visuals that are not in the catalogue wait on a binary.
That view is SwiftUI. There is no WKWebView in the path.
Scrolling and gestures#
Nested scroll is the usual WebView failure mode. A page that is "just a web home" inside a native tab bar will fight the outer pan. Bounce physics differ. Pull to refresh is yours to reimplement twice.
SDUI pull to refresh is a page-level flag the backend can set (RefreshModel.pullToRefresh) and PageStore can honour. The gesture is SwiftUI's. Horizontal widget carousels are still work, but they are SwiftUI work, not WKWebView work.
Swipe-to-pop belongs to the navigation controller or NavigationStack. WebViews steal it unless you configure carefully. Native widgets do not.
Accessibility and Dynamic Type#
Web accessibility on iOS is better than it was. It is still a different tree. Custom widgets in HTML need ARIA. Custom widgets in SwiftUI need traits and labels. You will do accessibility work in both stacks. Native SDUI at least shares the tree with Settings and Mail.
Dynamic Type in SDUI flows through text atoms into SwiftUI Text. In a WebView it flows through CSS and a viewport you have to test on every iPhone size.
Performance, said carefully#
Do not cite a number you did not measure on your page. Qualitatively: HTML has a JS runtime and a layout engine you do not control. SwiftUI has a view graph you do control. Either can be slow if you decode a huge payload on the main actor or ship giant images.
SDUI cost is decode plus view construction. Keep payloads reasonable. Paginate. Do not send a thousand widgets because the CMS has no pagination UI.
WebView cost is process spin-up, JS parse, and CSS. Fine for a rare help article. Painful if every tab is a WebView.
Operations and ownership#
WebView UI is owned by whoever owns the website. That can be a superpower (one CMS) or a deadlock (web and iOS visual language diverge).
SDUI UI is owned by whoever owns the page JSON and the widget catalogue. Backend and mobile have to share a schema. That is a meeting. It is also how you keep the page feeling native.
App Review: HTML you already could load is not a new trick. JSON that rearranges compiled widgets is data. JavaScript you download and eval is the 2.5.2 conversation. Neither renderer is a loophole. Read Apple.
Shared code is the third option, briefly#
Flutter and React Native still ship UI as code. A padding change waits on Play Store and App Store. That is a different article. Mention it here only so you do not collapse three choices into two. WebView versus SDUI is renderer. Cross-platform versus native is toolkit. You can do SDUI on Flutter too. This site is SwiftUI.
Image loading and fonts#
A WebView loads images through HTML. SDUI loads images through a host FlowImageLoader (or your own image view inside a widget). Fonts in SDUI are FontData plus whatever you registered in the app. Web fonts in a WebView are a CSS problem and a licensing problem. Do not assume "server driven" unifies them.
When teams actually pick WebView#
- Partner checkout that is web-only
- Content authored as long-form HTML
- A tool that is a web app and will never get native widgets
- A prototype due Friday
When teams pick SDUI#
- Feeds, merchandising, onboarding, help as structured widgets
- Experiments that change order and copy weekly
- Old binaries that must skip unknown types instead of failing the page
- A design system that is already SwiftUI
Questions this article should close#
Can SDUI embed a WebView as one widget?#
You can register a widget whose body is WKWebView. That widget is a destination-shaped hole, not a page strategy. Use it for partner HTML. Do not wrap the whole home in it and call the page native.
Will SDUI make the app smaller than a WebView?#
Not automatically. You still ship SwiftUI, images, and widget code. You drop the need to ship a second design language in CSS for that surface. Measure binary size if it is a goal. Do not assume.
Read next#
SDUI vs WebViews is not a religion. It is whether the page should share a view tree with the rest of the app.
Related documentation
Related articles
- Server-Driven UI4 min read
API driven UI and remote UI, explained
API driven UI and remote UI are names for the same idea as server driven UI: the API returns page structure, the iOS app paints SwiftUI.
- Server-Driven UI4 min read
Backend driven UI vs server driven UI
Backend driven UI, server driven UI, BDU, and SDUI are the same split: the server describes the page, the client renders native views.
- Server-Driven UI5 min read
SDUI for Swift: a practical definition
SDUI for Swift is a JSON envelope, an open widget registry, and a renderer. Not a new language, not a downloaded script.
More on the blog.
Read the source
Flow-UI is MIT licensed. The schema, renderer and starter widgets live on GitHub.
GitHubGet started with Flow-UI
Install the Swift package, register a widget, and render a page from JSON.
Get started