Skip to content
Flow-UILive
On this page

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.

Ayush MishraPublished 5 min read

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.

HomePage.swiftswift
let store = PageStore(pageID: "home", loader: loader, registry: registry)
FlowPageView(store: store)

That view is SwiftUI. There is no WKWebView in the path.

swift
registry.register(OrderCardWidget.self)

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
The Flow-UI mark: two nodes joined through a filled centre

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.

SDUI vs WebViews is not a religion. It is whether the page should share a view tree with the rest of the app.

More on the blog.

Read the source

Flow-UI is MIT licensed. The schema, renderer and starter widgets live on GitHub.

GitHub

Get started with Flow-UI

Install the Swift package, register a widget, and render a page from JSON.

Get started