TL;DR
- A2UI is Google's open standard for Generative UI that allows agents to describe interfaces as declarative data rather than executable code
- Agents can now compose interactive multi-step flows with bi-directional surfaces where user actions trigger agent re-renders, enabling full booking or search workflows within a single conversation
- A2UI Express inference format reduces latency by up to 3x compared to direct JSON generation, and decision models like Jev can achieve up to 80x speedup for layout decisions
- The framework is transport-agnostic and renders across React, Angular, Flutter, Lit, Jetpack Compose, Vue, and even terminal interfaces with the same A2UI output
- Basic Catalog Size
- 18 general-purpose primitives
- Express Latency
- Up to 3x faster than JSON
- Token Efficiency
- 3x fewer tokens with Express
What Changed: From Text Responses to Runtime-Generated UIs
Until now, agents could only respond with prose descriptions. A user asking for holiday packages would receive wall-of-text lists with dates, hotels, flights, and prices, but no interactive way to filter, select, or book directly within the conversation. Generative UI shifts this paradigm: agents now generate interfaces at runtime, shaped by what each specific request needs.
A2UI (Agent-to-UI) is Google's framework-agnostic open standard that enables this shift. Instead of agents outputting HTML, JavaScript, or raw code, they describe an interface as declarative data. The agent specifies which components to render and with what data; the client application interprets and draws that UI using its own trusted components. This approach is secure by design: since A2UI is data, not executable code, the client maintains a catalog of allowed components and anything outside that set is caught before rendering.
How It Works: Agents, Catalogs, and Renderers
A2UI operates across a spectrum of control. At one end, developers define components in advance and the agent picks which ones to render and with what data—brand-safe but less personalized. At the other end, agents could generate raw HTML or JavaScript, offering flexibility at the cost of design-system drift and code-execution risk. A2UI's declarative mode sits in the middle: agents assemble pre-declared components from a trusted catalog using a common language.
The setup has two parts. On the backend, you connect your agent to CopilotKit, which supports agent frameworks including Google ADK, LangChain, Mastra, and Strands through the AG-UI protocol. On the frontend, you define a component catalog—which building blocks the agent is allowed to use, mapped to your actual React, Angular, or Vue components. The Basic Catalog ships 18 general-purpose primitives for layout, display, input, and containers, but most production apps define custom catalogs with domain-specific components like flight cards, maps, or date pickers.
CopilotKit provides the integration stack, chat surface, and runtime. A2UI renders are available for React, Angular, Lit, SwiftUI, Jetpack Compose, Flutter, and community renderers for Vue and even the terminal. The same A2UI response works across all of these, so frontend developers ship building blocks once and the agent composes them per request. Payloads are flat lists of small JSON messages that reference each other by ID, making them LLM-friendly and streamable: the agent emits incrementally and the client renders components as they arrive.
from fastapi import FastAPI
from google.adk.agents import LlmAgent
from ag_ui_adk import ADKAgent, add_adk_fastapi_endpoint
root_agent = LlmAgent(
name="flight_agent",
model="gemini-3.8-flash",
instruction="Help users find and book flights. Call generate_a2ui to show results.",
)
adk_agent = ADKAgent(
adk_agent=root_agent,
app_name="flights",
user_id="demo_user",
use_in_memory_services=True,
)
app = FastAPI()
add_adk_fastapi_endpoint(app, adk_agent, path="/")Bi-Directional Surfaces and Multi-Step Flows
A2UI surfaces are reactive and bi-directional, enabling multi-step workflows within a single conversation. Traditional generative UI is one-shot: the agent renders something static that becomes stale immediately. With A2UI, any user action—selecting dates, choosing a flight, entering passenger details—sends values back along the same stream. The agent re-emits the surface with those values, allowing the full booking flow (search, results, passenger entry, confirmation) to live on one surface.
This works through inputs bound to data paths and buttons carrying actions that name which paths to send back. Client-side validation runs before the agent sees anything, so invalid email addresses show inline errors without a model call. Nothing reaches the agent until the button fires. When it does, the client sends the bound values and the agent regenerates against the same surface ID, keeping the entire interaction coherent.
{ "id": "cabin", "component": "ChoicePicker", "variant": "mutuallyExclusive",
"options": [ { "label": "Economy", "value": "eco" },
{ "label": "Business", "value": "biz" } ],
"value": { "path": "/booking/cabin" } },
{ "id": "confirm", "component": "Button", "child": "confirm_label",
"action": { "event": { "name": "confirmBooking",
"context": { "cabin": { "path": "/booking/cabin" },
"email": { "path": "/booking/email" } } } } }Performance: Express Format and Decision Models
A2UI Express, a new intermediate inference format, reduces latency by up to 3x compared to direct JSON generation. Generating JSON trees constrained by complex JSON schemas is slow and error-prone for LLMs. Express is optimized for inference speed and accuracy, requiring up to 3x fewer tokens to generate the same UI. Agents emit Express format, and deterministic code in the A2UI Agent SDKs compiles it into standard JSON-based transport messages.
Beyond swappable inference formats, decision models like Typesafe's Jev can achieve up to 80x speedup by making layout decisions from pre-defined schemas. Agents no longer need to generate every UI detail; they can delegate layout assembly to faster, deterministic decision models. You set the inference format with a single argument when creating the generator, and the SDK generates both the prompt instructions and the compiler automatically from your catalog's schema.
Getting Started and Built-In Resilience
Starting an A2UI and CopilotKit application takes one command: use the CopilotKit create CLI with the a2ui framework flag. The CopilotKit Dojo provides runnable examples covering fixed server-side schemas, dynamic schemas against custom catalogs, and error-recovery flows.
A2UI includes several built-in safeguards inherited by every AG-UI integration. The catalog is sent to the agent at setup, so registering it on the client is all it takes. UI generation runs in a dedicated sub-agent, keeping the catalog and protocol rules out of your main agent's context window. Invalid generations are caught with specific error feedback sent back for correction, so nothing broken reaches the screen. If retries exhaust, the surface resolves to a short message and the conversation continues instead of failing entirely.
npx copilotkit@latest create --name my-app --framework a2uiSource
Google Developers Bloghttps://developers.googleblog.com/build-generative-ui-apps-with-a2ui-copilotkit-agents/AI-assisted, verified against the source. This post was drafted with AI from the primary source linked above and checked automatically against it. For anything you depend on, read the original.
- #generativeui
- #aiagents
- #googlea2ui
- #copilotkit
- #llmapplications


