Welcome back, intrepid AI explorer! In the previous chapter, we got a taste of what A2UI can do, seeing how AI agents can conjure up rich user interfaces instead of just plain text. It’s pretty magical, right? But how does that magic actually work? How does an AI agent tell a UI what to display?
That’s exactly what we’re going to uncover in this chapter! We’ll peel back the layers and dive into the heart of A2UI: its declarative schema. Think of the schema as the blueprint or recipe that agents use to describe the UI they want. By the end of this chapter, you’ll understand the fundamental building blocks of A2UI, how to define common UI components, and how to structure your agent’s UI output using JSON. Get ready to transform abstract ideas into concrete interface elements!
This chapter assumes you have a basic familiarity with JSON structure, which is the language A2UI uses to describe interfaces. If you need a quick refresher, just remember JSON uses key-value pairs and arrays to organize data.
The A2UI Schema: Your UI Blueprint
At its core, A2UI is a declarative UI protocol. What does “declarative” mean in this context? It means that an AI agent declares or describes the desired state of the user interface, rather than providing step-by-step instructions on how to draw it. The agent says, “I want a button with this label,” not “Draw a rectangle, then put text inside it.” This is a powerful concept because it allows the same A2UI description to be rendered beautifully across different platforms (web, mobile, desktop) by specialized “renderers,” without the agent needing to know the specifics of each platform.
How it Works: Agent, Schema, Renderer
Let’s visualize this flow:
- AI Agent: Your agent code (which we’ll start building in later chapters) processes information and decides what UI elements are needed.
- A2UI JSON: The agent generates a JSON object that adheres to the A2UI schema. This JSON is the universal language of A2UI.
- A2UI Renderer: A client-side application (like a web browser, a mobile app, or a desktop client) receives this A2UI JSON. It has an A2UI renderer built-in, which knows how to interpret the JSON and translate it into native, interactive UI components for its specific platform.
- Interactive User Interface: The user sees and interacts with the rendered UI.
The Root of Every A2UI Description
Every A2UI output from your agent starts with a consistent, top-level JSON structure. Let’s break it down:
{
"apiVersion": "a2ui.dev/v1alpha1",
"kind": "View",
"spec": {
// This is where your actual UI components go!
}
}
Let’s look at each part:
apiVersion: This field specifies the version of the A2UI protocol your agent is using. It’s crucial for compatibility. As of late 2025,a2ui.dev/v1alpha1is the current stable API version, indicating it’s an early but robust release. Versioning helps ensure that renderers understand the structure your agent is sending.kind: This tells the renderer what type of top-level A2UI object this JSON represents. Commonkinds includeView(a general-purpose display),Form(for user input), orModal(for pop-up interfaces). For most basic UIs,Viewis your go-to.spec: Short for “specification,” this is the most important part! Thespecobject contains the actual definition of your user interface components. It’s the canvas where you’ll arrange all your buttons, text, images, and more.
Why these fields? Think of it like a mailing address. apiVersion is the country code, kind is the city, and spec is the detailed street address. Without them, the renderer wouldn’t know where to deliver your UI!
Essential A2UI Components
Inside the spec object, you’ll define a hierarchy of UI components. A2UI provides a set of standard components that cover most common UI needs. Each component has a type (e.g., Text, Button, Image) and a properties object that defines its specific attributes.
Let’s explore a few fundamental components:
1. Text Component
The Text component is exactly what it sounds like: it displays text!
type:"Text"properties:text(string, required): The actual text content to display.style(object, optional): An object containing semantic styling hints (e.g.,color,fontSize,fontWeight). Remember, these are hints for the renderer, not pixel-perfect CSS.id(string, optional): A unique identifier for this component, useful for updating specific parts of the UI later.
Example Snippet:
{
"type": "Text",
"properties": {
"text": "Welcome to A2UI!",
"style": {
"fontSize": "large",
"fontWeight": "bold",
"color": "blue"
}
}
}
2. Button Component
A Button allows users to trigger actions.
type:"Button"properties:label(string, required): The text displayed on the button.onTap(object, optional): AnActionobject that specifies what happens when the button is tapped. This is how the user communicates back to the agent!id(string, optional): A unique identifier.style(object, optional): Styling hints.
Example Snippet:
{
"type": "Button",
"properties": {
"label": "Continue",
"onTap": {
"type": "SendAgentMessage",
"payload": {
"message": "User wants to continue."
}
}
}
}
Here, SendAgentMessage is a common Action type that tells the agent to receive a message. We’ll dive deeper into actions later!
3. Image Component
The Image component displays, well, an image!
type:"Image"properties:src(string, required): The URL of the image to display.alt(string, optional): Alternative text for accessibility, important for screen readers.width(number, optional): Preferred width in logical units.height(number, optional): Preferred height in logical units.id(string, optional): A unique identifier.
Example Snippet:
{
"type": "Image",
"properties": {
"src": "https://example.com/a2ui_logo.png",
"alt": "A2UI Logo"
}
}
4. Layout Components (Column, Row)
To arrange multiple components, A2UI provides layout components like Column and Row. These are crucial for creating structured UIs.
Column: Arranges itschildren(other components) vertically.Row: Arranges itschildrenhorizontally.
Both Column and Row have a crucial children property:
type:"Column"or"Row"properties:children(array of objects, required): An array containing the A2UI component objects that this layout component should arrange.id(string, optional): A unique identifier.style(object, optional): Styling hints for the container itself.
Example Snippet (Conceptual):
{
"type": "Column",
"properties": {
"children": [
// Component 1 (e.g., Text)
// Component 2 (e.g., Button)
// Component 3 (e.g., Image)
]
}
}
This children array is how you nest components, building up complex UIs from simple parts.
Step-by-Step Implementation: Building Your First A2UI View
Let’s create a simple A2UI JSON that an agent could generate. Our goal is to display a welcome message and a button that, when clicked, tells the agent something.
We’ll build this in a hypothetical my_first_a2ui.json file.
Step 1: Initialize the Basic A2UI Structure
First, let’s set up the root apiVersion, kind, and the empty spec object.
Create a file named my_first_a2ui.json and add the following:
// File: my_first_a2ui.json
{
"apiVersion": "a2ui.dev/v1alpha1",
"kind": "View",
"spec": {
// Our UI components will live here!
}
}
This is our canvas. We’re declaring that this JSON describes a View using the v1alpha1 A2UI protocol.
Step 2: Add a Column for Layout
Since we’ll have multiple items (a text and a button), let’s wrap them in a Column to stack them vertically. The spec object usually contains a single root component, which is often a layout component like Column or Row.
Modify my_first_a2ui.json:
// File: my_first_a2ui.json
{
"apiVersion": "a2ui.dev/v1alpha1",
"kind": "View",
"spec": {
"type": "Column", // Our root component is a Column
"properties": {
"children": [
// This is where we'll add our Text and Button
]
}
}
}
Notice how Column itself is a component with a type and properties. Its properties include the children array, which will hold our other UI elements.
Step 3: Add a Text Component
Now, let’s add a friendly welcome message inside our Column’s children array.
Modify my_first_a2ui.json:
// File: my_first_a2ui.json
{
"apiVersion": "a2ui.dev/v1alpha1",
"kind": "View",
"spec": {
"type": "Column",
"properties": {
"children": [
{
"type": "Text", // Our first component: Text
"properties": {
"text": "Hello, A2UI Explorer! Ready for adventure?" // Its text content
}
}
]
}
}
}
We’ve added an object to the children array. This object defines our Text component. It has a type of "Text" and a properties object containing its text.
Step 4: Add a Button Component with an Action
Next, let’s add a button. This button will have a label and, importantly, an onTap action. When the user taps this button, it will send a message back to our agent.
Modify my_first_a2ui.json:
// File: my_first_a2ui.json
{
"apiVersion": "a2ui.dev/v1alpha1",
"kind": "View",
"spec": {
"type": "Column",
"properties": {
"children": [
{
"type": "Text",
"properties": {
"text": "Hello, A2UI Explorer! Ready for adventure?"
}
},
{ // Don't forget the comma after the Text component's closing brace!
"type": "Button", // Our second component: Button
"properties": {
"label": "Let's Go!", // The button's label
"onTap": { // The action to perform when tapped
"type": "SendAgentMessage",
"payload": {
"message": "User clicked 'Let's Go!' button."
}
}
}
}
]
}
}
}
Now we have a complete A2UI JSON object that an agent could generate. It describes a simple UI with a welcome message and an interactive button.
If you were to feed this JSON to an A2UI renderer (like the ones in the official quickstart demos), you would see a screen with “Hello, A2UI Explorer! Ready for adventure?” followed by a button labeled “Let’s Go!”. Clicking that button would then trigger the SendAgentMessage action, sending the specified payload back to the agent. Pretty neat, huh?
Mini-Challenge: Enhance Your A2UI View!
Your turn to practice!
Challenge: Modify the my_first_a2ui.json file to include an Image component above the “Hello, A2UI Explorer!” text. Use a placeholder image URL and provide meaningful alt text.
Hint:
- You’ll need to add another object to the
childrenarray of theColumn. - Remember the
typefor images is"Image". - Look for the
srcandaltproperties for theImagecomponent. - You can use a placeholder image like
https://via.placeholder.com/150forsrc.
What to Observe/Learn: How to integrate a new component into an existing layout and manage the order of elements within the children array.
Take your time, try it out, and don’t worry if you make a mistake – that’s how we learn!
Click for Solution (if you get stuck!)
// File: my_first_a2ui.json (Solution)
{
"apiVersion": "a2ui.dev/v1alpha1",
"kind": "View",
"spec": {
"type": "Column",
"properties": {
"children": [
{
"type": "Image", // New Image component!
"properties": {
"src": "https://via.placeholder.com/150",
"alt": "Placeholder for A2UI icon"
}
},
{ // Don't forget the comma!
"type": "Text",
"properties": {
"text": "Hello, A2UI Explorer! Ready for adventure?"
}
},
{
"type": "Button",
"properties": {
"label": "Let's Go!",
"onTap": {
"type": "SendAgentMessage",
"payload": {
"message": "User clicked 'Let's Go!' button."
}
}
}
}
]
}
}
}
Common Pitfalls & Troubleshooting
As you start working with A2UI JSON, you might run into a few common issues:
- Invalid JSON Structure: JSON is strict! Missing commas between objects in an array, extra commas after the last item, unclosed braces (
{}), or mismatched brackets ([]) are common errors. Use a JSON linter or formatter (many text editors have them built-in) to quickly spot these.- Tip: If your JSON isn’t rendering, the first thing to check is its validity. Online JSON validators are your friend!
- Incorrect
typeorpropertiesNames: A2UI components and their properties are case-sensitive and have specific names (e.g.,"Text", not"text"or"Label"instead of"label"). Double-check the official A2UI documentation for the exact names of components and their properties.- Tip: Typos are silent killers! Always refer to the schema or known working examples.
- Misplaced
childrenArrays: Remember,childrenarrays are typically found within layout components likeColumn,Row, or sometimes directly under the rootspecif thekindimplies a direct container. You can’t just putchildrenanywhere.- Tip: If you’re trying to add multiple components and they’re not appearing or causing errors, ensure they are correctly nested within a layout component’s
childrenarray.
- Tip: If you’re trying to add multiple components and they’re not appearing or causing errors, ensure they are correctly nested within a layout component’s
Summary
Phew! You’ve just taken a significant step in understanding how A2UI works behind the scenes. Let’s recap the key takeaways from this chapter:
- A2UI is Declarative: Agents describe what UI they want using a JSON schema, leaving the how to platform-specific renderers.
- Core Structure: Every A2UI output starts with
apiVersion(a2ui.dev/v1alpha1as of late 2025),kind(e.g.,View), and aspecobject. - UI Components: The
speccontains a hierarchy of components, each with atype(e.g.,Text,Button,Image,Column,Row) and apropertiesobject. - Properties Define Behavior: Component
properties(liketext,label,src,onTap) dictate their appearance and interactivity. - Layout with
children: Layout components likeColumnandRowuse achildrenarray to arrange other components vertically or horizontally. - Actions Enable Interactivity: Properties like
onTapcan holdActionobjects (e.g.,SendAgentMessage) to define how user interactions communicate back to the agent.
You’re now equipped with the fundamental knowledge of how to read and write basic A2UI JSON. In the next chapter, we’ll start bridging the gap between this JSON and an actual agent, exploring how an agent can dynamically generate these structures based on its internal logic. Get ready to bring your agents to life with dynamic UIs!
References
- Introducing A2UI: An open project for agent-driven interfaces
- A2UI Official Documentation: What is A2UI?
- A2UI Official Documentation: Quickstart
- Getting Started with A2UI: Your First Component
This page is AI-assisted and reviewed. It references official documentation and recognized resources where relevant.