AI Generative UI with Dynamic Components in React Native
Three architectures hide under one buzzword. The workable one bounds capability at build time and gives the model composition only.
TL;DR
Generative UI in a shipped React Native app means the model emits data, never code: a JSON component tree validated against a schema and rendered from a fixed registry of pre-built native components, the server-driven UI pattern with a model as composer. Executing model-generated JavaScript on device is both an injection risk and an App Review 2.5.2 violation, so capability stays bounded at build time while composition goes dynamic at runtime. Most apps need only build-time agent generation; the runtime layer earns its keep in AI chat widgets, server-tuned feeds, and context-assembled forms. Start the registry from a free VP0 design so the parts are designed before the model composes them.
What does “generative UI” actually mean in a shipped iOS app?
Three different architectures hide under the buzzword, and they have very different relationships with reality:
| Approach | What the model produces | When it runs | Where it stands |
|---|---|---|---|
| Agent-generated components | Real React Native code, reviewed and committed | Build time | Proven; this is the Claude Code / Cursor workflow |
| Server-driven UI (SDUI) | Nothing; humans define JSON layouts | Runtime, no AI | Proven for a decade at the big marketplaces |
| Model-emitted SDUI | JSON component trees, schema-validated | Runtime | The genuinely new layer, workable with hard guardrails |
The first row is ordinary modern development: the AI writes components before review, and nothing model-generated executes on a user’s phone. The interesting and risky territory is the third row, where a model assembles screens while the app is live, and the entire question becomes what, exactly, you allow it to emit.
Why must the model emit data, never code?
Two walls, one technical and one legal. The technical wall: executing model-generated JavaScript on device is an injection vulnerability with extra steps, since a hallucinated or adversarially-prompted component has the same privileges as your real ones. The App Store wall: Apple’s review guidelines (2.5.2) bar apps from downloading and executing code that changes the app’s behavior, and a runtime stream of fresh component logic is precisely that.
The architecture that satisfies both walls is the one server-driven UI proved years before LLMs arrived: the wire format is a JSON tree of component references, and the app renders it from a fixed registry of pre-built native components. The model can compose a screen from Card, PriceRow, SparkLine, and CTAButton; it cannot invent a fifth component, because the renderer simply has nothing to map an unknown type to. Capability is bounded at build time, composition is dynamic at runtime, and review rules stay satisfied because every behavior shipped through the store.
Validation is the second half of the contract. Every model emission gets checked against a JSON Schema (or a zod equivalent) before the renderer sees it: allowed component types, allowed props, depth limits, list-length limits. A failed parse falls back to a static layout, never to a crash and never to “render what we got.” The Vercel AI SDK (24,703 stars, with the ai package at 14,227,326 weekly downloads) popularized exactly this tool-call-to-component mapping on the web, and the RN translation keeps the mapping while swapping the registry to native components.
Where does dynamic UI actually earn its keep?
Not on your core screens. Navigation, checkout, settings, anything App Review walks through, should be boring, committed code. The dynamic layer earns its keep where layouts genuinely cannot be known at build time:
- AI chat surfaces that answer with widgets: a flight card, a comparison row, a chart instead of a paragraph. This is the canonical use, and the reason the pattern exists.
- Server-tuned merchandising: a home feed whose module order and composition change per campaign without a release. This is classic SDUI; adding a model just automates the composer.
- Form flows assembled per context: an intake flow that includes the three relevant sections out of twenty, composed against the schema.
The discipline that keeps all three sane: design the registry components as a real design system with fixed spacing and variants, so any composition the model produces still looks like your app. A registry of well-designed parts constrains the model the way a component library constrains a junior developer, and the comparison across libraries in the 2026 component library roundup applies unchanged here, since the registry is just a curated subset of whichever system you picked. The same registry thinking on the web side is covered in the headless WordPress generative UI build.
What goes wrong in practice?
Four failure modes account for most of the pain. Latency: a screen that waits on a model round trip feels broken, so dynamic compositions render behind skeletons with cached fallbacks, and anything interactive arrives pre-composed rather than streamed mid-interaction. Schema drift: the registry evolves, old cached compositions reference retired props, and the renderer must treat unknown props the way browsers treat unknown CSS, ignoring them silently. Testing: model-composed screens explode the snapshot space, so you test the registry components exhaustively and the compositions statistically, with the schema validator as the real gate. And accessibility: a model will happily compose six nested cards with no heading order, so accessibility roles live on the registry components themselves, not in the model’s hands.
Start the registry from screens that already work: a free VP0 design gives the agent real structure for the component set itself, and the dynamic layer then composes parts that were each designed on purpose.
What to choose
Build-time agent generation covers most apps completely: the screens are known, the agent writes them, review reads them. Reach for runtime dynamic UI only when layouts genuinely cannot be known in advance, and then build it as SDUI with a model-shaped composer: fixed native registry, schema-validated JSON on the wire, static fallbacks, and accessibility baked into the parts. The model gets composition, never capability.
Frequently asked questions
How do I build AI generative UI with dynamic components in React Native? Build a fixed registry of pre-built native components, let the model emit a JSON component tree validated against a schema, and render by mapping types to the registry. Model-generated code never executes on device. Start the registry itself from a free VP0 design so the parts the model composes are well-designed before composition starts.
Is runtime-generated UI allowed in the App Store? JSON-driven layout rendered from components that shipped in the binary is established practice (server-driven UI). Downloading executable code that changes app behavior violates guideline 2.5.2. The line is data versus code: a model may compose, it may not program.
When is generative UI better than just generating components with Cursor? Only when the layout cannot be known at build time: AI chat that answers with widgets, server-tuned feeds, context-assembled forms. For known screens, agent-written committed code is simpler, faster, and easier to review.
How do I stop the model from producing broken or ugly screens? Constrain it three ways: a schema validator that rejects unknown types and props before render, registry components with fixed spacing and variants so compositions inherit the design system, and static fallbacks when validation fails. Accessibility roles live on the components, not the model.
What stack handles the model-to-UI plumbing? The Vercel AI SDK established the tool-call-to-component mapping pattern; in React Native you keep that mapping and point it at your native registry, with zod or JSON Schema as the wire contract and your normal state layer underneath.
More questions from VP0 vibe coders
How do I build AI generative UI with dynamic components in React Native?
Build a fixed registry of pre-built native components, have the model emit a JSON component tree validated against a JSON Schema or zod contract, and render by mapping types to the registry with static fallbacks on validation failure. Model-generated code never executes on device. A free VP0 design gives the agent real structure for the registry components themselves.
Is runtime-generated UI allowed in the App Store?
JSON-driven layout rendered from components shipped in the binary is established server-driven UI practice and fine. Downloading executable code that changes app behavior violates guideline 2.5.2. The compliance line is data versus code: the model composes screens from existing parts, it never ships new behavior.
When is generative UI better than generating components at build time?
Only when layouts cannot be known in advance: AI chat that answers with widget cards, server-tuned merchandising feeds, and form flows assembled per context. For every known screen, agent-written committed code is simpler to test, review, and ship.
How do I keep model-composed screens from looking broken?
Three constraints: a schema validator that rejects unknown component types, props, and excessive depth before rendering; registry components carrying fixed spacing, variants, and accessibility roles so compositions inherit the design system; and cached static fallbacks so a failed parse renders a real screen, never an error.
What is the difference between server-driven UI and generative UI?
The wire format and renderer are identical: JSON trees mapped to a native registry. The difference is the composer: SDUI layouts are authored by humans or rules, generative UI lets a model assemble them within the same schema constraints. Proven plumbing, new author.
Part of the React Native & Expo: Mobile Frontend Architecture hub. Browse all VP0 topics →
Keep reading
LangChain React Native Boilerplate: The Thin Client
LangChain belongs on your server, not the bundle. The boilerplate is a thin streaming client: token-by-token UI, honest tool use, server-owned state.
Flutter to React Native Migration: The AI Tool Question
No converter exists; the method does: logic ported under tests, screens rebuilt natively against the running app, and channels re-bridged as Turbo Modules.
How to Obfuscate React Native Code in an AI App
Hermes already ships bytecode, not source. Obfuscation is a speed bump; the work that matters is moving secrets and entitlements off the device.
RAG Document Upload Progress UI in React Native
It is a pipeline, not a step: upload, extract, chunk, embed, index. Stepped progress, per-stage failure, and limits shown before the metered processing.
AI Lip Sync Video Player UI in React Native: The Loop
Build an AI lip-sync video app: the server-side pipeline truth, honest processing queues, a before-after player, dub track switching, and consent as architecture.
Clean Architecture React Native AI Template: 3 Layers
A pragmatic clean architecture template for AI-built React Native apps: three layers, inward dependencies, repository contracts agents code against.