This document outlines the required features for a new renderer implementation of the A2UI protocol. It is intended for developers building new renderers (e.g., for React, Flutter, iOS, etc.).
NOTE: Version Notes
This guide primarily describes the v0.8 message flow. v0.9 renames several messages (
surfaceUpdate→updateComponents,dataModelUpdate→updateDataModel,beginRendering→createSurface) and uses a flatter component format. See the v0.9 specification for details.
If you're building a renderer for the web (React, Vue, Svelte, etc.), you don't need to implement message processing, state management, or schema validation from scratch. The @a2ui/web_core package (web_core) provides all the framework-agnostic logic that the maintained Lit, Angular, and React renderers share.
| Module | What it does |
|---|---|
MessageProcessor |
Processes the A2UI JSONL stream, dispatches messages, manages surface lifecycle |
SurfaceModel / SurfaceGroupModel |
State management for surfaces, components, and data models |
DataModel / DataContext |
Data binding resolution, path-based lookups, template list rendering |
ComponentModel |
Component tree state, adjacency list → tree resolution |
| Types & Schemas | TypeScript types for all A2UI components, primitives, colors, styles, and JSON schema validation |
| Expression parser | Client-side function evaluation (v0.9) |
All three web renderers follow the same pattern — web_core handles the protocol, the renderer handles the UI:
// Types — shared across all renderers
import type * as Types from '@a2ui/web_core/types/types';
import type * as Primitives from '@a2ui/web_core/types/primitives';
// v0.8: Message processing and state
import { A2uiMessageProcessor } from '@a2ui/web_core/data/model-processor';
// v0.9: Message processing, surfaces, catalogs
import { MessageProcessor } from '@a2ui/web_core/v0_9';
import { SurfaceModel } from '@a2ui/web_core/v0_9';
// Styles and layout helpers
import * as Styles from '@a2ui/web_core/styles/index';Your renderer only needs to:
- Map A2UI component types to your framework's components (e.g.,
Text→<p>,Button→<button>) - Subscribe to state changes from
web_coreand re-render - Forward user actions back through the
MessageProcessor
See the React renderer, Lit renderer, and Angular renderer for working examples of this pattern.
web_core exports both v0.8 and v0.9 APIs:
@a2ui/web_core/v0_8or@a2ui/web_core(default) — stable v0.8@a2ui/web_core/v0_9— v0.9 withcreateSurface, custom catalogs, client-side functions@a2ui/web_core/v0_9/basic_catalog— v0.9 basic catalog expression parser and built-in functions
TIP: Start with
web_coreBuilding a web renderer without
web_coremeans reimplementing ~3,000 lines of message processing, state management, and schema validation. Unless you have a specific reason to diverge, use it.
This section details the fundamental mechanics of the A2UI protocol. A compliant renderer must implement these systems to successfully parse the server stream, manage state, and handle user interactions.
A compliant renderer must implement the following message processing and state management features:
- JSONL Stream Parsing: Implement a parser that can read a streaming response line by line, decoding each line as a distinct JSON object.
- Message Dispatcher: Create a dispatcher to identify the message type (
beginRendering,surfaceUpdate,dataModelUpdate,deleteSurface) and route it to the correct handler. - Surface Management:
- Implement a data structure to manage multiple UI surfaces, each keyed by its
surfaceId. - Handle
surfaceUpdate: Add or update components in the specified surface's component buffer. - Handle
deleteSurface: Remove the specified surface and all its associated data and components.
- Implement a data structure to manage multiple UI surfaces, each keyed by its
- Component Buffering (Adjacency List):
- For each surface, maintain a component buffer (e.g., a
Map<String, Component>) to store all component definitions by theirid. - Be able to reconstruct the UI tree at render time by resolving
idreferences in container components (children.explicitList,child,contentChild, etc.).
- For each surface, maintain a component buffer (e.g., a
- Data Model Store:
- For each surface, maintain a separate data model store (e.g., a JSON object or a
Map<String, any>). - Handle
dataModelUpdate: Update the data model at the specifiedpath. Thecontentswill be in an adjacency list format (e.g.,[{ "key": "name", "valueString": "Bob" }]).
- For each surface, maintain a separate data model store (e.g., a JSON object or a
Implement the following rendering logic:
- Progressive Rendering Control:
- Buffer all incoming
surfaceUpdateanddataModelUpdatemessages without rendering immediately. - Handle
beginRendering: This message acts as the explicit signal to perform the initial render of a surface and set the root component ID.- Start rendering from the specified
rootcomponent ID. - If a
catalogIdis provided, ensure the corresponding component catalog is used (defaulting to the standard catalog if omitted). - Apply any global
styles(e.g.,font,primaryColor) provided in this message.
- Start rendering from the specified
- Buffer all incoming
- Data Binding Resolution:
- Implement a resolver for
BoundValueobjects found in component properties. - If only a
literal*value is present (literalString,literalNumber, etc.), use it directly. - If only a
pathis present, resolve it against the surface's data model. - If both
pathandliteral*are present, first update the data model atpathwith the literal value, then bind the component property to thatpath.
- Implement a resolver for
- Dynamic List Rendering:
- For containers with a
children.template, iterate over the data list found attemplate.dataBinding(which resolves to a list in the data model). - For each item in the data list, render the component specified by
template.componentId, making the item's data available for relative data binding within the template.
- For containers with a
Implement the following communication features:
- Event Handling:
- When a user interacts with a component that has an
actiondefined, construct auserActionpayload. - Resolve all data bindings within the
action.contextagainst the data model. - Send the complete
userActionobject to the server's event handling endpoint.
- When a user interacts with a component that has an
- Client Capabilities Reporting:
- In every A2A message sent to the server (as part of the metadata), include an
a2uiClientCapabilitiesobject. - This object should declare the component catalog your client supports via
supportedCatalogIds(e.g., including the URI for the standard 0.8 catalog). - Optionally, if the server supports it, provide
inlineCatalogsfor custom, on-the-fly component definitions.
- In every A2A message sent to the server (as part of the metadata), include an
- Error Reporting: Implement a mechanism to send an
errormessage to the server to report any client-side errors (e.g., failed data binding, unknown component type).
To ensure a consistent user experience across platforms, A2UI defines a standard set of components. Your client should map these abstract definitions to their corresponding native UI widgets.
The standard catalog includes the following basic content components:
- Text: Render text content. Must support data binding on
textand ausageHintfor styling (h1-h5, body, caption). - Image: Render an image from a URL. Must support
fit(cover, contain, etc.) andusageHint(avatar, hero, etc.) properties. - Icon: Render a predefined icon from the standard set specified in the catalog.
- Video: Render a video player for a given URL.
- AudioPlayer: Render an audio player for a given URL, optionally with a description.
- Divider: Render a visual separator, supporting both
horizontalandverticalaxes.
The standard catalog includes the following layout and container components:
- Row: Arrange children horizontally. Must support
distribution(justify-content) andalignment(align-items). Children can have aweightproperty to control flex-grow behavior. - Column: Arrange children vertically. Must support
distributionandalignment. Children can have aweightproperty to control flex-grow behavior. - List: Render a scrollable list of items. Must support
direction(horizontal/vertical) andalignment. - Card: A container that visually groups its child content, typically with a border, rounded corners, and/or shadow. Has a single
child. - Tabs: A container that displays a set of tabs. Includes
tabItems, where each item has atitleand achild. - Modal: A dialog that appears on top of the main content. It is triggered by an
entryPointChild(e.g. a button) and displays thecontentChildwhen activated.
The standard catalog includes the following interactive and input components:
- Button: A clickable element that triggers a
userAction. Must be able to contain achildcomponent (typically Text or Icon) and may vary in style based on theprimaryboolean. - CheckBox: A checkbox that can be toggled, reflecting a boolean value.
- TextField: An input field for text. Must support a
label,text(value),textFieldType(shortText,longText,number,obscured,date), andvalidationRegexp. - DateTimeInput: A dedicated input for selecting a date and/or time. Must support
enableDateandenableTime. - MultipleChoice: A component for selecting one or more options from a list (
options). Must supportmaxAllowedSelectionsand bindselectionsto a list or single value. - Slider: A slider for selecting a numeric value (
value) from a defined range (minValue,maxValue).