Generative UI on native mobile: how an agent draws real product UI
Generative UI on the web streams React components. On iOS and Android it has to become a typed spec over a fixed native catalogue. Here is why, and how it works.
About this article
Generative UI is an agent choosing the interface as well as the words. On the web that means streaming React components to a runtime that can evaluate them. On iOS and Android you cannot ship a component at runtime, so the agent emits a typed JSON spec instead, and that spec selects from a fixed catalogue of native views the app already shipped.
Ask an assistant for your account balance and it can reply with a sentence. Ask it inside your banking app and a sentence is the wrong answer, because your app already knows how to draw a balance. It has a view for that, with the right typeface, the right currency formatting, a tap target that meets your accessibility bar, and a follow-up chip that opens the transaction list.
Generative UI is the name for letting the agent pick that view. On the web the pattern is settled and documented. On iOS and Android it has almost no written account at all, which is odd, because the constraint that makes it interesting is a mobile constraint.
What generative UI means, and what changes on native#
Generative UI means the model decides which interface to show, not only what text to emit. Vercel’s AI SDK gives the tightest definition available: it is “the process of connecting the results of a tool call to a React component”. The model calls a tool, the tool returns data, and a component renders that data instead of a paragraph describing it.
The definition travels. The implementation does not. A browser can receive code it has never seen and run it. An iOS or Android app cannot: the binary was compiled, signed and reviewed before the conversation started. So on native, the agent cannot send a view. It can only send instructions for choosing and filling a view that is already there.
That single constraint produces a different architecture, and a better security story as a side effect.
The web answer, and why it does not port#
There are two mature web implementations of this idea, and a careful reading of both explains why neither reaches a native app.
Streaming components assumes a runtime that can evaluate them#
Vercel’s server-streamed variant, AI SDK RSC, sends React server components down the wire as the
model produces them. It is worth noting what Vercel says about it in their own docs:
“AI SDK RSC is currently experimental. We recommend using AI SDK UI for production.”
The production-recommended path keeps components in the client bundle and streams only tool state,
using three documented states, input-available, output-available and output-error.
Even the production path assumes a JavaScript runtime that can be handed new component trees. Ship that to an App Store binary and you are shipping an interpreter. Apple’s review rules have opinions about that, your binary grows, and your offline behaviour becomes a second implementation of everything.
HTML in an iframe is not a native interface#
The MCP Apps extension takes the other route, and it is a serious piece of work. Its overview opens
with the right problem statement: “Text responses can only go so far. Sometimes users need to
interact with data, not just read about it.”
The mechanism is a tool description carrying a _meta.ui.resourceUri, a ui:// resource holding an
HTML page, and a host that mounts it. The spec, versioned 2026-01-26, is explicit about where that
page runs: “MCP Apps run in a sandboxed iframe controlled by the host. They can’t access the parent
page, steal cookies, or escape their container.”
An iframe is a sound answer for a chat host that is already a browser. Inside a native app it reintroduces the web layer you left, with its own scroll physics, its own font stack, its own accessibility tree and its own offline story. CopilotKit, who build on the same handshake, write the limitation into their own comparison page: MCP Apps is “Web-first: not yet a good fit for non-web surfaces such as mobile or Slack.”
The evidence that the pattern is worth the trouble#
Two 2026 papers make the case that this is worth solving rather than abandoning. Chen and colleagues, in Generative Interfaces for Language Models (ACL 2026 Findings), report that “generative interfaces consistently outperform conversational ones, with up to a 72% improvement in human preference.” Keep the “up to” attached; it is their hedge and it is doing work.
The more useful paper is Google’s, because of what it concedes. In Generative UI: LLMs are Effective UI Generators (24 February 2026), Leviathan and colleagues report that “when ignoring generation speed, results generated by our implementation are overwhelmingly preferred by humans over the standard LLM markdown output”, and then, in the next sentence: “while the results generated by our implementation are worse than those crafted by human experts, they are at least comparable in 50% of cases.”
Read those two sentences together and you have the whole design argument. Generated interfaces beat walls of text. Human-designed interfaces beat generated ones. The right place to land is the combination: interfaces your designers built, chosen at runtime by the model.
The native answer: a closed catalogue and a typed spec#
The mobile version of generative UI has two halves. The app ships a fixed catalogue of views. The agent emits a typed spec that names one of them and fills it.
Nothing executable crosses the wire. A payload is a small JSON object with a kind field that
selects a view and a handful of data fields that populate it. Every view in the catalogue was written
by your team, in Swift or Kotlin or Dart, reviewed the way the rest of your app is reviewed, and
compiled into the binary. The model’s freedom is real but bounded: it decides which of your views the
answer deserves and what goes in it.

This is also the answer to the question people ask next, which is how it differs from server-driven UI. It does not differ much, and that is the point: server-driven UI already has a decade of mobile practice behind it, and Thoughtworks put it in the Trial ring of its Technology Radar in Volume 34, April 2026, noting that “by separating rendering into a generic container while providing structure and data via the server, mobile teams can bypass lengthy app store review cycles for every iteration.” Generative UI on native is server-driven UI where the server is an agent. The schema work you would have done anyway is the same schema work, and it matters more, because the thing filling the schema is now probabilistic.
Walking one payload from model to native view#
Here is a real shape, trimmed to its skeleton. The model has called a balance tool, received rows, and now has to decide how to present them.
{
"kind": "stat",
"title": "Available balance",
"value": "EGP 48,250.00",
"caption": "Next settlement Thursday",
"actions": [
{ "label": "Show transactions", "prompt": "show my last transactions" }
]
}Four fields and a small array. kind selects the view type. The rest fill it. actions becomes
follow-up chips, each carrying the prompt it would send, so a tap continues the conversation rather
than deep-linking out of it.
On iOS that resolves to a SwiftUI view the app compiled months ago. The model never learns SwiftUI, never emits a layout, and never chooses a font size. It chooses a widget kind.

And here is the same mechanism having actually run, on a device, against Paymob’s backend. The account is the shared test merchant we develop against, so every figure comes back zero.

The same catalogue, in a different product, produces something that looks nothing like a balance card, because a different set of views was registered.

The five objections, answered#
The objections to generative UI are good ones, and they are already written down. The best collection is a Hacker News thread from December 2025 titled “What Is Generative UI?”, where people who build interfaces for a living explain what worries them. Every one of those objections is an objection to free-form generation. A catalogue answers them individually.
Consistency#
The sharpest version comes from the commenter bccdee: “Personalized interfaces are bad. I don’t want to configure anything, and I don’t want anything automatically configured on my behalf.” They go on: “Your UI should be clear and predictable. A chatbot should not be moving around the buttons.”
This is correct, and a catalogue does not move the buttons. The balance card renders identically for every user who asks about their balance. What varies between turns is which card appears, in the same way that tapping a different tab shows a different screen. The user is choosing, by asking.
Reproducibility and support#
Also from that thread, tartoran: “You won’t remember how you got there or did what because there are n permutations of getting there or doing that, except they’re vaguely similar but not exactly the same thing.” And the support consequence, imagined by marcyb5st as a line from a future support call: “Yeah, I cannot reproduce your issue because things on my end look different”.
With a closed catalogue, n is not unbounded: it is the number of widget kinds, and it is printed in
your docs. A support engineer reproduces a session by replaying the same spec, because the spec is
logged, small, and fully determines the render. That is strictly easier to reproduce than a hand-built
screen whose state came from six sources.
Documentation#
You cannot document an interface that is generated fresh each time. You can document thirteen widget kinds, their fields, and the conditions under which the agent picks each one, because that is a finite list that changes when you change it. The widget catalogue is a documented artefact, reviewed like an API, and versioned like one.
UI impersonation and injection#
This is the objection with teeth, and it is the one where the native answer is strongest rather than merely adequate. Greshake and colleagues showed in Not what you’ve signed up for (February 2023) that “processing retrieved prompts can act as arbitrary code execution, manipulate the application’s functionality, and control how and if other APIs are called”, demonstrated against real systems including Bing’s GPT-4 powered Chat.
If the model’s output is markup, an injected instruction can produce a convincing fake login prompt.
If the model’s output is a kind from a fixed list plus data fields, the worst it can produce is a
real widget containing wrong text. Someone made this argument on the A2UI thread in December 2025,
independently of any vendor, the commenter epec254: “Most HTML is actually HTML+CSS+JS - IMO,
accepting this is a code injection attack waiting to happen. By abstracting to JSON, a client can
safely render UI without this concern.”
The rebuttal on that same thread deserves quoting too, from lunar_mycroft: “If the JSON protocol in question supports arbitrary behaviors and styles, then you still have an injection problem even over JSON.” That is exactly right, and it is why the catalogue has to stay closed. A spec format with an escape hatch for arbitrary styling has quietly become a markup language with extra steps. The defence is the constraint, not the file format. What the catalogue is actually buying you, in full, is a longer argument than fits here.
What happens when the model asks for a widget you do not have#
It asks. Models generalise, and sooner or later yours will emit "kind": "seat_map" because a
seat map is obviously what that answer wanted. The handling has to be decided before it happens.
The spoken answer still arrives, so the turn is not lost. And the rejected kind is logged, which turns a failure into a roadmap: the widgets your agent keeps reaching for are the widgets your catalogue is missing.
That last point is worth making concretely. WCAG 2.2, a W3C Recommendation since 12 December 2024, requires under success criterion 2.5.8 that pointer targets be “at least 24 by 24 CSS pixels”. You can satisfy that once, in twelve views, and know it holds for every answer the agent ever gives. You cannot promise it for markup a model wrote thirty seconds ago.
What this is not#
It is not the model writing your app. Nothing about this pattern generates Swift, generates layout code, or edits your project. The catalogue is designed by designers and built by engineers on the normal schedule.
It is also not a way to skip design work. Google’s own result says human experts still produce the better interface. What changes is when the choosing happens: at runtime, per question, instead of at build time, per screen. Your team still decides what a good balance card looks like. The agent decides that this question deserves one.
Nor is it finished as an industry. Flutter’s first-party attempt is honest about its status: the
genui package docs, updated 19 August 2026, state that “the
genui package is in alpha and is likely to change.” The specs are young, the protocols disagree
with each other, and anyone claiming this is settled is selling something. What is already true is
that the native constraint has a good answer, and that answer is older and duller than the web’s:
define a schema, keep it closed, and let the agent fill it, which is the settled part of a decade of
server-driven-UI practice rather than anything the last two years invented. Deciding what the user sees during the
second before the spec arrives is a separate problem, and a
surprisingly large share of the felt quality. So is the shape of the JSON contract
itself, which is where most of the design arguments actually happen.
Two more pieces sit either side of the contract. The server-driven UI case stated on its own terms, costs included, is the argument to read if you are being asked to justify the schema to someone who did not want it. And a search answer assembled from a whole sentence is the case where the temptation to let the model lay out the page is strongest, and where a closed catalogue earns its keep most visibly.
Common questions#
What is generative UI?#
Generative UI is a model choosing the interface as well as the content of a reply. Instead of answering in prose, it selects a component or a widget appropriate to the answer and fills it with the data a tool call returned.
How is generative UI different from server-driven UI?#
They are the same mechanism with a different author. Server-driven UI has a backend send a structured description of a screen that the client renders from views it already has. Generative UI has a model produce that description. The client contract, and most of the engineering difficulty, is identical, which is why the decade of server-driven-UI practice linked earlier is the most useful literature available.
Can an LLM generate native iOS or Android UI, not just HTML?#
Not directly, and it should not try. A signed binary cannot evaluate views it was not compiled with. What works is a typed spec: the model emits JSON naming a widget kind from a fixed catalogue, and the app draws the matching native view. The result is native, and the model wrote no view code.
Is generative UI safe? What stops the model rendering something malicious?#
With free-form markup, nothing does, and indirect prompt injection is a demonstrated attack against real deployed systems. With a closed catalogue the model cannot author markup at all. It can only name a kind from a list and supply data fields, so the worst outcome is a genuine widget showing wrong text, which your confirm gate is there to catch before anything is written.
How do you keep a generated interface consistent enough to support?#
By making the set of possible renders finite and logging the spec. Every balance answer produces the same balance card. A support engineer replays the logged spec and sees exactly what the user saw, because the spec fully determines the render.
Sources#
- Vercel, Generative User Interfaces, AI SDK documentation. Accessed 12 September 2026.
- Vercel, Streaming React Components, AI SDK RSC documentation. Accessed 12 September 2026.
- CopilotKit, Generative UI. Accessed 12 September 2026.
- Model Context Protocol, MCP Apps extension overview, specification version 2026-01-26. Accessed 12 September 2026.
- Jiaqi Chen, Yanzhe Zhang, Yutong Zhang, Yijia Shao and Diyi Yang, Generative Interfaces for Language Models, arXiv:2508.19227, ACL 2026 Findings.
- Yaniv Leviathan and colleagues, Generative UI: LLMs are Effective UI Generators, arXiv:2604.09577, 24 February 2026.
- Flutter, Generative UI. Page last updated 19 August 2026.
- Thoughtworks, Server-driven UI, Technology Radar Volume 34, April 2026.
- Hacker News, What Is Generative UI?, submitted 3 December 2025.
- Hacker News, A2UI: A Protocol for Agent-Driven Interfaces, submitted 16 December 2025.
- Kai Greshake, Sahar Abdelnabi, Shailesh Mishra, Christoph Endres, Thorsten Holz and Mario Fritz, Not what you’ve signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection, arXiv:2302.12173, 23 February 2023.
- W3C, Web Content Accessibility Guidelines (WCAG) 2.2, W3C Recommendation, 12 December 2024.
Next
The catalogue of every widget kind the agent can ask your app to draw, and the payload each one takes.
See every widget kind the agent can renderThe rest of Render spec
Open the clusterServer-driven native UI: the agent names the widgets, your app draws them, and shipping a new answer shape stops requiring an app release.
- Shipping UI without a release: the case for server-driven UIWhy mobile teams move layout decisions to the server, what it costs in versioning and coupling, and what changes when an agent is the thing choosing the shape.8 min
- In-app search when the query is a whole sentenceHow search inside an app breaks when people speak in sentences, and how to build the search tool an agent can actually call.7 min
- How a render spec turns one JSON payload into native UIThe whole contract is a spoken answer, a separator, and an array of widget objects. The interesting parts are the constraints, not the format.10 min
- The first 300 milliseconds of an agent turnYou cannot make the model faster from the client. Almost all of the felt wait is decided before the model has said anything, and that part is yours.10 min
- Server-driven UI was already the answer. LLMs made it urgent.Server-driven UI and generative UI are one idea arriving from two directions, and a decade of mobile practice already tells you which parts are hard.10 min
- A catalogue beats free-form generation, and the objections say whyEvery serious objection to generative UI is an objection to free-form generation. A fixed catalogue answers all four without giving up the idea.10 min
Elsewhere on the map
- Adding an AI agent to a Flutter app, and what GenUI gives youThe platform-channel integration, and an honest comparison with Flutter's own GenUI SDK: what the alpha covers, what production needs, and which to pick.Integration8 min
- In-app agents that finish the task instead of answeringAn assistant that describes where a setting lives competes with your own navigation. One that completes the request does not. What changed, and what to build.Agent basics8 min
- Does your agent work eight times out of eight?Average accuracy is the wrong number for a product. Run the same task eight times and count how often it worked every single time.Safety11 min
