Thesys C1 on iOS: What a Web‑Only Generative UI Engine Can’t Do Natively (and How to Generate SwiftUI from AI Safely)
If you’re trying to generate native iOS UI from LLM responses, the details of how that UI gets rendered matter a lot.

If you’re trying to generate native iOS UI from LLM responses, the details of how that UI gets rendered matter a lot.
On the web, tools like Thesys C1 / OpenUI Cloud make it easy to stream generative UI into React. But on iOS, dropping a web-only runtime into a WKWebView is not the same as generating SwiftUI from AI.
This article compares web-first generative UI engines (like Thesys C1), classical server-driven UI (SDUI), and Uzori’s AI-powered SwiftUI runtime. We’ll focus on what you can and can’t do natively on iOS, and how Uzori combines deterministic schemas with flexible AI layouts for dynamic user interfaces.
As of August 2026, all product descriptions and claims in this article reflect the publicly documented state of Thesys OpenUI Cloud, DivKit, and related tools.
Best tools to turn LLM responses into native iOS interfaces (2026)
Before going deep on Thesys C1’s iOS limitations, it helps to frame the main options teams actually use today to turn LLM responses into native iOS interfaces:
- Web-first generative UI runtimes
- Example: Thesys C1 / OpenUI Cloud
- Primary target: React on the web
- iOS story: embed via
WKWebViewor React Native bridges
- Classical server-driven UI (SDUI) frameworks
- Example: DivKit
- Primary target: native iOS/Android + web
- iOS story: server sends layout JSON; client renders native components deterministically
- Native generative UI with server validation
- Example: Uzori iOS SDK (SwiftUI)
- Primary target: SwiftUI-first, iOS-native
- iOS story: AI composes screens; server validates; client renders SwiftUI views
Each category optimizes for different tradeoffs: reach, fidelity, and control. The rest of this article unpacks those tradeoffs from an iOS engineer’s perspective.
Thesys C1 on iOS: web‑only generative UI engine limitations
What Thesys C1 / OpenUI Cloud actually ships today
As of August 2026, Thesys markets OpenUI Cloud (formerly C1 API) as a runtime that turns LLM outputs into live interfaces using a React SDK. Their public docs describe primitives like C1Component, C1Chat, a ThemeProvider, and React rendering hooks — all centered on web/React.
- Their official positioning is: runtime generative UI for web/React.
- There is no publicly documented SwiftUI-native renderer at the time of writing.
- On iOS, this implies one of:
- A
WKWebViewembedding a web runtime, or - A React Native shell around their React SDK, or
- A custom bridge that you, as the iOS team, would have to build.
- A
In other words, Thesys is a strong engine for web generative UI, but on iOS it is, by default, a web-only generative UI engine.
Why web-only generative UI is not “native” on iOS
Apple’s own docs describe WKWebView as a way to present HTML/CSS/JavaScript content inside a native app, while SwiftUI is the framework for declaring native interface elements on iOS and other Apple platforms.
That distinction matters:
- A
WKWebViewcan show generative UI content, but:- It does not directly compose SwiftUI views.
- It runs inside a JavaScript engine, with its own layout and event loop.
- It can’t reuse your SwiftUI components or modifiers without translation layers.
React Native’s performance guidance reminds us that mobile UIs target 60 fps, which leaves about 16.67 ms per frame for layout and drawing. The same docs explicitly call out WebView-based tools as the baseline alternative when true native performance and feel matter.
- React Native docs: 60 fps → ~16.67 ms per frame budget for smooth UX (reactnative.dev).
In practice, this means:
- Any complex, streaming AI UI rendered inside a WebView:
- Shares CPU with JavaScript and layout engines.
- Can be more sensitive to network jitter.
- Often feels different from the rest of the app’s native controls.
UX and performance risks of web-first AI UI on iOS
Even though Akamai’s performance stats come from retail web, they’re a useful proxy for why sluggish, web-rendered AI UI is risky:
- 53% of mobile site visitors abandon pages that take longer than 3 seconds to load (Akamai, retail performance report).
- A 100 ms delay can hurt conversion by 7% (same report).
- A 2-second delay can increase bounce rates by 103%.
While your app is not a web page, users carry the same expectations:
- Long AI-thinking spinners in a WebView feel like a slow website.
- Micro-delays in scrolling or interactions can be jarring compared to native screens.
- Accessibility and platform behaviors (like system text size, dynamic type) require extra wiring.
Where Thesys C1 still shines
Thesys C1 / OpenUI Cloud is not a bad product; it’s a web-first product.
They report (vendor claims):
- 10,000+ developers using their OpenUI/C1 architecture (Thesys blog, OpenUI).
- Validation that reduced malformed output error rates from 3% to under 0.3% (vendor claim, same source).
- An OpenUI format that can save up to 67% tokens vs JSON when describing UI (OpenUI GitHub).
Their own blogs argue against “just generate front-end code,” emphasizing the value of a constrained schema + purpose-built renderer for production generative UI.
The key question for iOS teams is: do you want that renderer to be web-first or native-first?
Classical server-driven UI vs generative UI on iOS
How classical SDUI works (DivKit as the reference)
DivKit is one of the clearest examples of modern SDUI:
- Supports Android, iOS, and Web.
- All elements are implemented natively for each platform (divkit.tech).
- The backend sends a structured schema describing:
- Templates
- States and animations
- Timers and triggers
- Layout hierarchies
On iOS, a DivKit runtime:
- Fetches a JSON layout from the server.
- Parses it into typed structures.
- Maps elements to native UIKit/SwiftUI components.
- Renders a deterministic screen.
Benefits:
- Safe: server fully controls structure.
- Predictable: no runtime UI improvisation.
- Update-friendly: change layout without app releases.
Limitations:
- Non-intelligent: the server doesn’t “think” about the user’s intent in the moment.
- You still handcraft flows, even if they’re described as JSON.
How generative UI differs
Nielsen Norman Group’s definition of generative UI is:
- Interfaces generated in real time for a user’s needs and context.
- Designers focus on user goals and constraints, not hardcoding every screen (NN/g, 2024).
Their 2026 update highlights how buttons, checkboxes, and form fields appear inline inside AI chats, emphasizing that the end-user’s experience gets shaped in real time, not just the words.
Google Research similarly reports that their generative UI prototypes:
- Create fully customized visual experiences for any prompt.
- Were preferred by human raters when generation speed was ignored (Google Research, 2024).
So generative UI differs from SDUI in one core way:
The layout logic itself is AI-driven, but it still needs a safe schema and renderer.
Uzori: generating SwiftUI from AI with server‑driven safety
Uzori sits at the intersection of:
- Generative UI (AI composes layouts on the fly), and
- Server-driven UI (server-approved schema, native runtime).
Instead of using a WebView, Uzori’s iOS SDK is a SwiftUI-first runtime. AI doesn’t just respond with text; it responds with SwiftUI screens built from a constrained schema and validated on your server.
How to generate SwiftUI from AI: streaming, validation, and server checks
At a high level, Uzori’s flow looks like this:
- User asks for something
- Example: “Help me configure roaming protection for my trip.”
- This request is captured in your app (e.g., chat interface, voice, or a button).
- Your backend forwards context to Uzori’s AI engine
- Includes:
- User profile or session.
- Relevant backend APIs (OpenAPI spec, endpoints) for the task.
- Business constraints and capabilities.
- Includes:
- AI composes a candidate screen tree in a constrained schema
- The AI uses Uzori’s schema to build a layout:
- Sections, stacks, lists, forms.
- SwiftUI-like components and controls.
- The AI uses Uzori’s schema to build a layout:
- Your server validates the AI-generated UI
- The generated UI description is returned to your server.
- Your backend checks:
- Schema validity (types, required fields).
- Business rules (no hidden pricing, no blocked endpoints, etc.).
- Security (no unapproved actions, endpoints, or arbitrary HTML/JS).
- The validated screen is streamed to the iOS app
- This happens over a streaming protocol (e.g., SSE or WebSocket).
- The SDK gradually builds the SwiftUI view hierarchy as chunks arrive.
- SwiftUI renders the interface natively
- The Uzori SDK maps elements in the schema to your SwiftUI components.
- Users interact with the screen like any other native view.
This approach lets you generate SwiftUI from AI while keeping control over structure and safety.
Example: a small SwiftUI schema Uzori might emit
Here’s a simplified, illustrative schema example (JSON) for a transaction dispute assistant screen:
{
"type": "screen",
"id": "dispute_status",
"title": "Where did my money go?",
"body": {
"type": "vstack",
"children": [
{
"type": "text",
"style": "headline",
"value": "Transaction dispute status"
},
{
"type": "list",
"items": [
{
"type": "status_step",
"title": "Bank received your claim",
"subtitle": "Submitted on 2026-08-18",
"state": "complete"
},
{
"type": "status_step",
"title": "Temporary credit applied",
"subtitle": "Pending",
"state": "active"
},
{
"type": "status_step",
"title": "Merchant response",
"subtitle": "Expected within 10 business days",
"state": "upcoming"
}
]
},
{
"type": "button",
"role": "primary",
"label": "View transaction details",
"action": {
"type": "navigate",
"destination": "transaction_detail",
"params": { "transaction_id": "txn_123" }
}
}
]
}
}
A corresponding SwiftUI mapping might look like this (pseudo-code):
struct UzoriScreenView: View {
let screen: UzoriScreen
var body: some View {
VStack(alignment: .leading, spacing: 16) {
Text(screen.title)
.font(.title2)
.bold()
List(screen.statusSteps) { step in
StatusStepRow(step: step)
}
Button(screen.primaryAction.label) {
handleAction(screen.primaryAction)
}
.buttonStyle(.borderedProminent)
}
.padding()
}
}
This is a native SwiftUI implementation, not HTML inside a WebView. You can insert your own StatusStepRow, use your design tokens, and integrate with your navigation stack.
For a deeper dive on building this kind of four-step dispute status flow, see our related guide: “Where did my money go? — a transaction dispute is a four-step status answer”.
Technical deep dive: server validation workflow and threat model
To understand the safety and latency tradeoffs, let’s break down the server validation workflow that Uzori uses.
Step-by-step API workflow
- Client → Your backend
POST /assistant/intent- Payload: user message, session ID, app context.
- Your backend → Uzori AI engine
POST /uzori/generate- Payload includes:
- User intent and context.
- Allowed operations / endpoints.
- OpenAPI spec or subset.
- UI schema capabilities (e.g., which components are allowed).
- Uzori AI engine → Your backend
- Response (streamed or batched):
- A candidate UI tree conforming to Uzori’s schema.
- Metadata about which backend calls are wired to which actions.
- Response (streamed or batched):
- Your backend: validation layer
- Steps:
- Schema validation
- Check JSON against Uzori’s schema (e.g., JSON Schema or typed struct mapping).
- Reject unknown types or malformed layouts.
- Business rule validation
- Ensure actions only call approved endpoints.
- Enforce pricing, feature flags, region restrictions.
- Check that no hidden or misleading content appears.
- Security validation
- No arbitrary code execution.
- No unapproved URLs or external hosts.
- Rate-limiting or abuse checks, if needed.
- Schema validation
- Steps:
- Your backend → iOS client
GET /uzori/streamor WebSocket stream.- Only validated UI chunks are sent to the device.
- iOS client renders SwiftUI
- The Uzori SDK converts each chunk into SwiftUI elements.
- Partial screens can be rendered as streaming continues.
Threat model: what this protects against
This pipeline is designed to mitigate several classes of risk:
- LLM hallucination in UI
- AI can propose layouts, but your rules enforce what’s allowed.
- Unapproved backend calls
- The AI can’t invoke endpoints outside your allowlist.
- Runtime code injection
- No arbitrary Swift/JS; only schema elements with known mappings.
- Inconsistent UX
- Schema ensures AI uses your components and patterns.
Latency implications
Server validation adds at least one extra hop:
- LLM inference time (Uzori AI engine).
- Plus your validation layer’s processing.
However, several design choices mitigate this cost:
- Streaming UI
- You can send initial skeleton layouts (e.g., headers, placeholders) while deeper elements are still being validated.
- Cached schemas and rules
- Validation can be cheap if it’s mostly schema checks and lightweight policy enforcement.
- Deterministic client-side rendering
- SwiftUI rendering is fast and predictable once the schema arrives.
In practice, the main latency budget is dominated by LLM inference, not the validation layer, especially if you’re already calling AI for reasoning.
Balanced perspective:
- If your AI use case is extremely latency-sensitive (sub-100 ms), any LLM-based UI composition may be too slow.
- For most assistant-like flows (roaming plans, disputes, product discovery), the extra validation hop is a worthwhile tradeoff for safety.
Uzori vs Thesys C1 vs DivKit: high-level comparison
Here’s a qualitative comparison across the three main categories.

This comparison chart summarizes how Thesys C1, DivKit, and Uzori differ on platform focus, rendering, and validation.
Rendering and platform focus
- Thesys C1 / OpenUI Cloud
- Primary runtime: React (web).
- iOS: WebView or JS-based approaches.
- Strength: mature, production-focused generative UI for browsers.
- DivKit
- Primary runtime: native on iOS, Android, and web.
- iOS: SDUI engine maps JSON layouts to native components.
- Strength: deterministic server-driven layout updates.
- Uzori
- Primary runtime: SwiftUI-only (iOS).
- iOS: generative UI layer that outputs native SwiftUI.
- Strength: AI-driven flows with server-validated schemas.
Intelligence vs determinism
- Thesys C1
- Generative UI engine with schema constraints.
- Strong for AI-driven web layouts.
- DivKit
- Non-intelligent; layouts are predefined on the server.
- Great when you want full designer control and predictable updates.
- Uzori
- AI composes layouts; server enforces constraints.
- Blends genUI and SDUI for adaptive flows.
Native iOS fidelity
- Thesys C1
- Native feel depends on your WebView integration and CSS.
- Harder to fully reuse SwiftUI components and patterns.
- DivKit
- Native components, but no on-device AI layout orchestration.
- Uzori
- Fully native SwiftUI rendering.
- Uses your existing design system and navigation stack.
Safety and validation
- Thesys C1
- Has its own validation and fallback layers (vendor claims), but mainly on the OpenUI + React path.
- DivKit
- Safety comes from deterministic server layouts.
- Uzori
- Explicit server-side validation between AI and device.
- You own the final approval of what hits the screen.
AI UX and flows
- Thesys C1
- Great for web-based AI dashboards, assistants, and tools.
- DivKit
- Good for static or rule-based flows you update server-side.
- Uzori
- Optimized for AI concierges, product explorers, and guided setup flows that need to feel like part of your app, not a separate chat bot.
Production use cases: when to choose Uzori over a web-only engine
1. AI concierges that feel like your app, not a chatbox
If you’re building an AI concierge for:
- Roaming plan configuration.
- Card dispute flows.
- Insurance coverage guidance.
…and you want it to:
- Use your existing SwiftUI components.
- Integrate with your navigation, deep links, and state.
- Feel indistinguishable from hand-built screens.
Then a native generative UI layer like Uzori is the best fit.
This is where our transaction dispute flow example lives: the AI turns “Where did my money go?” into a four-step status interface instead of a long wall of text. See: “Where did my money go? — a transaction dispute is a four-step status answer”.
2. Rapid iteration on AI flows without duplicating client code
If your product team is experimenting with:
- Multiple versions of onboarding or setup flows.
- Different wizards for complex configurations.
- Adaptive product explorers with filters, comparisons, and carousels.
You don’t want to:
- Hand-build each flow in SwiftUI.
- Maintain separate SDUI definitions and AI logic.
Uzori lets AI compose those flows from a single schema while your server enforces guardrails. You get AI-powered variations without rewriting your client.
3. When web-first AI UI is enough
There are cases where a web-only generative UI engine like Thesys C1 is actually fine:
- You’re building a web-first product and only lightly wrapping it in a shell app.
- Most users interact via browser, not native app.
- Your team is heavily invested in React and doesn’t want to maintain native SwiftUI at all.
In those cases, using Thesys C1 across web and mobile WebView can make sense.
4. When classical SDUI is the better choice
If:
- You have strict regulatory requirements.
- Your flows are well-understood and rarely change.
- You want deterministic, fully designed experiences.
Then a pure SDUI framework like DivKit may be preferable.
Generative UI is powerful, but it adds LLM inference dependencies and new operational concerns. For some flows, that’s unnecessary complexity.
Example: integrating Uzori’s iOS SDK in one screen
Here is a simplified pseudo-code example showing how an iOS team might integrate Uzori in a single SwiftUI screen.
import SwiftUI
import UzoriSDK
struct AIConciergeScreen: View {
@StateObject private var controller = UzoriController()
var body: some View {
UzoriView(controller: controller)
.onAppear {
controller.startSession(
endpoint: URL(string: "https://api.yourbackend.com/uzori/stream")!,
initialIntent: .text("Help me with roaming protection")
)
}
}
}
In this pattern:
UzoriViewis a container that:- Subscribes to your server’s streaming endpoint.
- Renders whatever validated SwiftUI schema it receives.
UzoriControllermanages:- Session lifecycle.
- User inputs forwarded back to your backend/AI.
From your perspective as an iOS engineer, it’s literally “one screen to integrate”. All the complexity lives in your backend and in Uzori’s AI + validation layer.
Balanced view: Uzori’s tradeoffs and limitations
No tool is a silver bullet. A realistic assessment of Uzori’s approach includes a few key tradeoffs.
1. Operational overhead and backend work
To get the most from Uzori, your backend needs to:
- Expose OpenAPI or equivalent descriptions of your APIs.
- Implement the validation gateway between AI and client.
- Monitor and log AI-generated UI flows for correctness.
This is work — and it’s a required investment if you want strong guardrails.
2. Latency and dependency on LLMs
Because layouts are AI-driven:
- Every new flow requires LLM inference, which adds latency.
- Outages or rate limits in your model provider can impact UI generation.
Mitigations include:
- Caching common flows.
- Fallbacks to pre-defined screens for critical paths.
3. Vendor lock-in and schema coupling
Uzori provides a specific schema and runtime. While it’s designed to be structured and clear:
- Your flows become coupled to Uzori’s view model.
- Migrating away requires either:
- Writing adapters to another SDUI/genUI framework, or
- Rebuilding certain flows.
This is similar to adopting any SDUI system — but worth acknowledging.
4. iOS-only focus
Uzori’s strength is being SwiftUI-native. If you:
- Need a fully cross-platform runtime (web, Android, iOS) with a single UI definition.
- Prefer web-first or React-first tooling.
Then a tool like Thesys C1 or a cross-platform genUI framework might be a better strategic fit.
How to decide: key criteria for iOS teams
When evaluating production-ready AI iOS interface tools in 2026, focus on:
- Rendering path
- Native SwiftUI vs WebView vs React Native.
- Does it reuse your design system and controls?
- Safety model
- Schema constraints and validation.
- Where is validation enforced — client, server, or both?
- Integration cost
- How many screens do you need to touch?
- How much backend work is required?
- Performance and latency
- Can it stream UI incrementally?
- How does it behave under poor network conditions?
- Ecosystem fit
- Is your app iOS-first or web-first?
- Do you have strong SwiftUI expertise, or is your team mostly JS?
Guidance:
- If you want AI-native UX that feels like your existing SwiftUI app, and you’re comfortable investing in a server validation layer, Uzori aligns best.
- If you want browser-first generative UI with occasional mobile shells, Thesys C1 / OpenUI Cloud is strong.
- If you want deterministic, non-AI SDUI, DivKit-style frameworks are still the reference.
FAQ: generating native iOS UI from LLM responses
Can I generate SwiftUI from LLM responses?
Yes. With Uzori, you can generate SwiftUI from AI by letting an LLM compose screens in a constrained schema, then rendering them through a SwiftUI runtime.
The key is to keep generation schema-bound and server-validated, rather than asking the model to emit arbitrary Swift code.
How do I validate AI-generated SwiftUI on the server?
A typical workflow:
- AI returns a schema-based UI description (not raw Swift).
- Your backend:
- Validates against a JSON Schema or typed structs.
- Applies business and security rules.
- Only approved UI descriptions are streamed to the client.
This ensures AI can’t introduce unsafe actions or layouts. Uzori is designed around this pattern.
What are the limitations of web-only generative UI engines on iOS?
Web-only engines like Thesys C1 / OpenUI Cloud are optimized for React/web. On iOS:
- They typically run inside
WKWebViewor JS-based shells. - They don’t natively reuse your SwiftUI components.
- Performance and UX can differ from the rest of your app.
For some use cases this is acceptable, but for high-fidelity native UX, a SwiftUI-native runtime is preferable.
Are server-driven UI and generative UI the same thing?
No:
- Server-driven UI (SDUI) sends deterministic layouts from the server. There is no AI in the loop.
- Generative UI uses AI to decide which layout to show for each user and context.
Tools like Uzori combine both: AI composes screens under a server-enforced schema, and the server still validates everything.
How do I choose between Thesys C1, DivKit, and Uzori for an iOS project?
- Choose Thesys C1 / OpenUI Cloud if:
- Web is your primary platform.
- You’re comfortable with WebView-based mobile experiences.
- Choose DivKit if:
- You want deterministic SDUI across iOS, Android, and web.
- You don’t need AI-driven layout decisions.
- Choose Uzori if:
- You want to generate native iOS UI from LLM responses.
- You care about SwiftUI fidelity and server-validated safety.
If you’re exploring AI-native experiences on iOS, start small:
- Wrap a single assistant feature (like a transaction dispute flow) behind a feature flag.
- Integrate Uzori on one screen.
- Measure whether AI-generated, server-validated SwiftUI helps you compress weeks of UI iteration into a streaming interface that designs itself.