A2UI Renderer Implementation Guide
A2UI Renderer Implementation Guide
Section titled “A2UI Renderer Implementation Guide”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.).
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.
Web Renderers: Use @a2ui/web-lib (web_core)
Section titled “Web Renderers: Use @a2ui/web-lib (web_core)”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-lib package (web_core) provides all the framework-agnostic logic that the maintained Lit, Angular, and React renderers share.
What web_core provides
Section titled “What web_core provides”| 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) |
How the maintained renderers use it
Section titled “How the maintained renderers use it”All three web renderers follow the same pattern — web_core handles the protocol, the renderer handles the UI:
/ Types — shared across all renderersimport type * as Types from '@a2ui/web_core/types/types';import type * as Primitives from '@a2ui/web_core/types/primitives';
/ v0.8: Message processing and stateimport { A2uiMessageProcessor } from '@a2ui/web_core/data/model-processor';
/ v0.9: Message processing, surfaces, catalogsimport { MessageProcessor } from '@a2ui/web_core/v0_9';import { SurfaceModel } from '@a2ui/web_core/v0_9';
/ Styles and layout helpersimport * 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.
Version support
Section titled “Version support”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
Start with
web_coreBuilding a web renderer withoutweb_coremeans reimplementing ~3,000 lines of message processing, state management, and schema validation. Unless you have a specific reason to diverge, use it.
I. Core Protocol Implementation Checklist
Section titled “I. Core Protocol Implementation Checklist”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.
Message Processing & State Management
Section titled “Message Processing & State Management”- 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
Rendering Logic
Section titled “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
Client-to-Server Communication
Section titled “Client-to-Server Communication”- 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).
II. Standard Component Catalog Checklist
Section titled “II. Standard Component Catalog Checklist”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.
Basic Content
Section titled “Basic Content”- 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.
Layout & Containers
Section titled “Layout & Containers”- 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.
Interactive & Input Components
Section titled “Interactive & 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).