---
title: "Overview"
icon: "lucide/FileJson"
description: "Render rich, declarative UI surfaces from your LangGraph agent using the A2UI protocol."
---

import { Callout } from "fumadocs-ui/components/callout"

[A2UI](https://a2ui.org) (Agent-to-UI) is a Declarative Generative UI specification led by Google, with CopilotKit as a launch and design partner. It lets your agent render structured UI components using a JSON-based schema. Instead of sending plain text, the agent produces surfaces — cards, lists, buttons, images — that render natively in the chat.

You can design and preview A2UI schemas visually using the [A2UI Composer](https://a2ui-composer.ag-ui.com/).

## Setup

Enable A2UI in your CopilotRuntime by adding `a2ui: true`, or pass an object to customise:

```typescript title="app/api/copilotkit/route.ts"
import { CopilotRuntime } from "@copilotkit/runtime";

// Simple — enable with defaults
const runtime = new CopilotRuntime({
  agents: { default: myAgent },
  a2ui: true,
});

// Or customise — e.g. inject a render tool into the agent
const runtime = new CopilotRuntime({
  agents: { default: myAgent },
  a2ui: {
    injectA2UITool: true,
  },
});
```

This tells the runtime to apply the A2UI middleware to your agents. The middleware intercepts tool results containing A2UI operations and renders them as rich UI surfaces in the chat.

<Callout type="warn">
Without `a2ui` configured in your CopilotRuntime, A2UI surfaces will not render — tool results will appear as plain text.
</Callout>

## Approaches

CopilotKit supports three approaches to A2UI, each with different tradeoffs:

- **[Fixed Schema](./fixed-schema)** — Pre-defined schema loaded from JSON. Agent provides data only. Fastest — no LLM schema generation.
- **[Fixed Schema (Streaming)](./fixed-schema-streaming)** — Same pre-defined schema, but cards appear one-by-one as the LLM streams data. Great for lists.
- **[Dynamic Schema](./dynamic-schema)** — A secondary LLM generates both the schema and data. Fully flexible — any UI from any prompt.

## When to use which?

| Approach | Schema source | Rendering | Best for |
|---|---|---|---|
| **Fixed Schema** | JSON file | Instant (all at once) | Known UI patterns (flight cards, product lists) |
| **Fixed Schema Streaming** | JSON file | Progressive (card by card) | Long lists where you want immediate feedback |
| **Dynamic Schema** | LLM-generated | Progressive (card by card) | Unknown/varied UI — the agent decides what to show |

<Callout type="info">
All three approaches use the same A2UI protocol and renderer. The difference is where the schema comes from and how data reaches the client.
</Callout>

## How it works

Every A2UI surface is built from three operations:

1. **`surfaceUpdate`** — defines the component tree (the schema)
2. **`dataModelUpdate`** — provides the data that populates the components
3. **`beginRendering`** — tells the client to start rendering

The CopilotKit Python SDK provides helpers to build these operations:

```python
from copilotkit import a2ui

a2ui.surface_update(surface_id, components)
a2ui.data_model_update(surface_id, {"items": data})
a2ui.begin_rendering(surface_id, root_id)
a2ui.render(operations)  # wraps and serializes
```

Continue to one of the approach guides above to see the full implementation.
