Skip to content
Flow-UILive
On this page

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.

Ayush MishraPublished 3 min read

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.

OrderCardWidget.swiftswift
struct OrderCardWidget: WidgetView {
    let content: OrderCardContent
    let context: WidgetContext
 
    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            Text(content.orderNumber.text)
        }
    }
}

Gestures you attach in that body are UIKit/SwiftUI gestures. They are not touch handlers in a web document.

swift
registry.register(OrderCardWidget.self)

What you inherit for free#

  • Scroll physics of ScrollView in FlowPageView
  • 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 ColorData includes dark_hex or tokens resolve through ThemeProvider
  • 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.

The Flow-UI mark: two nodes joined through a filled centre

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.

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.

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