An agent on another company’s server cannot safely inject React into your app. Sending HTML in an iframe works, but it rarely matches your design system, accessibility baseline, or security review.
A2UI — short for Agent-to-User Interface — is Google’s open answer: agents send declarative component descriptions as data. Your client validates them against a component catalog and renders with native widgets.
Key idea
A2UI is a UI payload protocol, not a transport. Messages can ride over A2A, AG-UI, REST, or other channels. The client always owns rendering and security.
The problem A2UI targets
Google’s A2UI announcement frames the scenario clearly. In a multi-agent mesh, the agent doing useful work is often remote — different server, different vendor, different trust zone. It cannot touch your view layer. Historically, cross-boundary UI meant sandboxed HTML/JS in iframes: heavy, visually disjoint, security-sensitive.
A2UI instead transmits UI that is safe like data, expressive like code — a flat, incrementally updateable JSON structure describing surfaces, components, and data bindings.
Core concepts
From a2ui.org and the specification:
| Concept | Meaning |
|---|---|
| Surface | A renderable UI region the agent creates or updates (createSurface in v0.9+) |
| Component | A node in a tree — Text, Button, TextField, Card, etc. from a catalog |
| Adjacency list | Flat component list with ID references — LLM-friendly, streamable |
| Data binding | Separates structure from values so agents can update data without rebuilding the tree |
| Catalog | Client-defined set of allowed components; agents cannot request arbitrary types |
| Client-side functions | User actions (clicks, submits) routed back to the agent as structured events |
flowchart LR A["Remote agent"] -->|"A2UI JSON"| T["Transport A2A / AG-UI"] T --> C["Client validator"] C --> R["Native renderer"] R --> U["Branded UI"] U -->|"action events"| A
Specification versions (as of 2026)
The A2UI spec index tracks:
| Version | Status | Notes |
|---|---|---|
| v0.8 | Legacy | Structured-output-first baseline |
| v0.9 | Stable | Prompt-first shift, createSurface, custom catalogs |
| v0.9.1 | Current | application/a2ui+json MIME type |
| v1.0 | Candidate | actionResponse RPC, action IDs, surfaceProperties |
The project is Apache 2.0, originated by Google with contributions from CopilotKit and the open community, with active development on GitHub.
Security model: catalog-bound rendering
A2UI’s security story is allowlisting, not sandboxing:
- The client publishes a catalog of trusted component types.
- The agent may only reference types in that catalog.
- The renderer maps abstract types to real implementations — your
Button, not a model’s<button onclick=...>.
This aligns with trusted rendering and component catalog patterns from Interface Lab’s foundation series. The LLM fills a contract; it does not author executable UI.
LLM-friendly design choices
A2UI optimizes for how models actually generate:
- Flat lists with IDs instead of deeply nested JSON — easier to stream and patch.
- Progressive rendering — partial trees display while generation continues.
- Incremental updates — agents send deltas as conversation state changes (e.g. restaurant booking form → time slot picker).
The restaurant finder quickstart demonstrates end-to-end flow: user message → agent emits A2UI → Lit/Angular/Flutter renderer → user action → agent updates surface.
Renderers and transports
Client renderers listed on a2ui.org:
- Web Components (Lit), Angular, Flutter, Markdown, and community ports
- Flutter GenUI SDK uses A2UI under the hood for server-driven generative UI
Transports:
- A2A — primary cross-agent path documented by Google
- AG-UI — CopilotKit integration for host apps
- REST and others — feasible, less standardized today
A2UI vs MCP Apps vs platform ChatKit
Google’s ecosystem post draws explicit comparisons (source):
| Approach | Mechanism | Tradeoff |
|---|---|---|
| A2UI | Declarative native component blueprint | Best brand/accessibility fit; requires renderer work |
| MCP Apps | ui:// HTML/JS resource in sandboxed iframe | Best cross-host interoperability; weaker native feel |
| OpenAI ChatKit | Integrated OpenAI ecosystem widgets | Optimized for OpenAI surfaces; less portable |
None replaces the others outright. An enterprise orchestrator on AG-UI might render orchestrator UI via A2UI while a plugged-in MCP tool returns an MCP App dashboard in an iframe.
Minimal example (illustrative shape)
Exact field names vary by spec version; the mental model is a stream of messages:
{
"createSurface": {
"surfaceId": "booking",
"catalogId": "com.example.app/v1"
}
}
{
"updateComponents": {
"surfaceId": "booking",
"components": [
{ "id": "title", "component": "Text", "text": "Reserve a table" },
{ "id": "date", "component": "DateInput", "label": "Date" },
{ "id": "submit", "component": "Button", "label": "Check availability", "action": "check_slots" }
]
}
}
Your renderer walks the adjacency list, mounts native components, and routes action events back to the agent. The agent responds with updated A2UI — not with imperative DOM instructions.
When to adopt A2UI
Strong fit:
- multi-agent systems with A2A across vendors;
- Flutter or web apps needing one agent payload, many native renderers;
- products that already invested in a component catalog;
- Gemini Enterprise / ADK-style orchestration (Google’s stated direction).
Weaker fit:
- you only ship inside MCP hosts — MCP Apps may be faster to market;
- your UI is prose-only with occasional markdown — structured output schemas suffice;
- you cannot maintain a catalog — without allowlisting, A2UI loses its main security advantage.
Product implication
A2UI makes generative UI portable without making it uncontrolled. Users see interfaces that feel native because they are native — composed from your components, styled by your tokens, tested by your QA.
For frontend leads, A2UI is the difference between “the agent team ships iframe demos” and “we own one renderer contract across web and mobile.”
What to watch next
The last major open UI extension in the tool layer is MCP Apps — interactive ui:// resources for MCP hosts like Claude, ChatGPT, and VS Code.
References: