What native means in an SDUI stack
Native SDUI means the widget is a real SwiftUI view: scrolling, gestures, and accessibility come from the platform, not from HTML.
Native SDUI means the widget is a real SwiftUI view. Scrolling, gestures, and accessibility come from the platform, not from HTML. The word "native" is abused in every SDUI pitch. This post pins it to something you can inspect in the view debugger.
Native is the view type, not the JSON#
JSON is data. It is not native or web. The renderer decides. If the renderer builds Text, Image, Button, and your OrderCardWidget, you are native. If it loads HTML into WKWebView, you are not.
Flow-UI widgets conform to WidgetView, which inherits View. The registry's makeView closure returns AnyView wrapping that type. That erasure is the only one. Your body is still SwiftUI.
Gestures you attach in that body are UIKit/SwiftUI gestures. They are not touch handlers in a web document.
What you inherit for free#
- Scroll physics of
ScrollViewinFlowPageView - Interactive pop, when you host inside the usual navigation
- Dynamic Type, when you use SwiftUI text (and atoms that feed it)
- VoiceOver, when your view uses standard controls and you send labels
- Dark mode, when
ColorDataincludesdark_hexor tokens resolve throughThemeProvider - Safe area, keyboard avoidance, Dynamic Island overlap: the same as the rest of the app
None of that is free if you reimplement a button as a Rectangle plus a tap gesture and forget the accessibility trait. Native is a floor, not a substitute for craft.
What you do not inherit#
You do not inherit a design system. Flow-UI ships atoms, not your brand. ThemeProvider maps tokens the backend already uses.
You do not inherit networking. PageLoader is host code.
You do not inherit a router. Deeplink actions are data.
You do not inherit App Review immunity. New widget types are still a binary.
Starter widgets are native examples#
The widget catalog is eight SwiftUI views: title block, image text card, banner, button row, tag rail, stepper row, accordion, separator. They exist so you can read real WidgetView code. Override any of them by registering the same type string last.
Accordion is the nesting example: children decode through the same registry. Nested native views, not nested HTML.
Platform idioms#
List rows that highlight on tap, context menus, swipe actions: those are SwiftUI APIs you opt into inside a widget. The backend can send an actions map. It cannot send "behave like UITableView" as a string and expect UIKit to appear magically unless you wrote that widget.
Haptics, UIImpactFeedbackGenerator, sensoryFeedback: your view. The schema should not pretend to be a full UIKit.
Layout chrome is native too#
Padding, margin, corners, and gradients are WidgetLayout applied by WidgetLayoutModifier in a fixed order: padding, width, background and gradient, clip, border, margin. Your widget body should not duplicate that chrome. Native does not mean each widget invents a card style. Native means the modifier is SwiftUI and the values came from JSON.
Why people still hear "native" as a lie#
Because some SDUI systems snapshot to images. Because some embed React Native. Because some really are WebViews with a native chrome. Ask what type you will see in the view debugger. That question ends the slogan.
Questions this article should close#
Does native mean I get Mail.app for free?#
No. You get SwiftUI behaviour for the views you wrote. A custom control still needs traits, labels, and Dynamic Type. Native is the toolkit, not a finished design system.
Can a widget be UIKit inside SwiftUI?#
UIViewRepresentable is still a native view. It is not a WebView. Use it when you wrap MapKit or a vendor scanner. Register that wrapper as the widget.
Read next#
Native in an SDUI stack means the widget is a SwiftUI view. Keep that test and the rest of the pitch has to stay honest.
Related documentation
Resources
FAQ
Is Flow-UI free, is server driven UI just WebViews, what happens on old app versions? Straight answers about SDUI on iOS and SwiftUI.
Widgets
Widget catalog
The eight starter widgets that ship with Flow-UI, each a worked example of rendering a server driven UI component as a native SwiftUI view.
Related articles
- Server-Driven UI4 min read
How to implement SDUI on iOS
Implement SDUI on iOS by decoding a page envelope, registering widgets, containing unknown types, and dispatching actions as data.
- Server-Driven UI4 min read
How to build server driven UI in SwiftUI
Build server driven UI in SwiftUI with four pieces: a JSON envelope, a widget registry, a renderer, and host networking. Worked path using Flow-UI.
- Server-Driven UI5 min read
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.
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