Skip to content
Flow-UILive

Introduction

Flow-UI is an open source server driven UI framework for SwiftUI. Your backend describes an iOS screen as JSON and Flow-UI renders it as native views.

Every screen in a Flow-UI app is data. Your backend describes a page as JSON, and Flow-UI decodes it, lays it out and renders it as native SwiftUI, with every margin, color, corner radius and interaction controlled by the response. Change the JSON and the app changes, no release train required.

Why server driven UI#

Mobile releases are slow. App review, staged rollouts and adoption curves mean a layout tweak can take weeks to reach everyone. Server driven UI moves the description of the screen to the place you can change instantly: your backend.

Flow-UI gives you that power without giving up what makes native apps good. Widgets are real SwiftUI views with real gestures, scrolling and animation. The backend decides what appears and how it is dressed; your Swift code decides how it behaves.

The mental model#

Three nouns cover the whole framework:

  • A page is one screen: navigation config, an optional sticky header and footer, sections, pagination and refresh behavior.
  • A section groups widgets and arranges them vertically, as a snapping carousel, or in a grid.
  • A widget is one typed component. Its type string selects the SwiftUI view, its data carries the content, and its layout carries the chrome.
json
{
  "page": {
    "id": "home",
    "sections": [
      {
        "layout": { "arrangement": "vertical", "item_spacing": 8 },
        "widgets": [
          {
            "type": "image_text_card",
            "data": { "title": "AirPods Pro 2" },
            "actions": { "tap": { "type": "open_bottom_sheet", "sheet": { } } }
          }
        ]
      }
    ]
  }
}

What makes Flow-UI different#

The registry is open. Adding a widget is one call, registry.register(OrderCardWidget.self), in your app. There is no framework enum to extend and no fork to maintain. Your widgets are indistinguishable from the built in ones.

Pages refuse to die. A widget type the client does not know, or a payload that fails to decode, is contained: the rest of the page renders, the problem is recorded with its exact key path, and debug builds show a labelled placeholder where the widget would have been. One bad widget never blanks a screen.

Interactions are data too. Widgets carry declarative actions: show a toast, open a server driven bottom sheet, call an API and apply the returned mutations, or anything you define. Handlers form an open chain, so deeplinks route through your existing router.

Zero dependencies. Flow-UI ships no networking, no image library and no design system. Those are seams: you plug in what your app already has.

Free and open source. Flow-UI is MIT licensed. Use it in commercial apps, fork it, or build your own widgets on top. There is no paid tier and no licence key.

The modules#

ModuleWhat it holds
FlowCoreThe schema and decoding layer. Foundation only, fully unit testable.
FlowRenderThe SwiftUI engine: registry, page and sheet renderers, actions, theming.
FlowWidgetsEight starter widgets, each one a worked example.

Import FlowUI for everything, or FlowCore alone for tooling and tests.