A2UI Protocol: How Agents Stream Layout Data Instead of HTML to Native UI Components A developer has introduced A2UI, an event-based protocol that lets AI agents stream schema-validated layout data—JSON events like component_add, component_update, state_sync, and stream_end—rather than HTML or JSX, which native adapters translate into React, Angular, Lit, Flutter, SwiftUI, and Jetpack Compose components without a WebView or eval(). The design confines agents to an application-defined, versioned component catalog, so invalid components or props are rejected on both the agent SDK and client sides, enforcing capability boundaries at the protocol level. The protocol targets low-latency streaming over HTTP streaming, WebSocket, or server-sent events for real-time agent interactions across web and mobile. Most agent UIs stream markdown or generate HTML strings. A2UI streams layout data that native framework adapters translate into platform components. The agent emits structured events describing buttons, cards, and forms. The client renders them using React, Flutter, SwiftUI, or Jetpack Compose without a WebView or eval . This separation creates strict capability boundaries. The agent cannot inject arbitrary code. It composes from a fixed catalog of components defined by the application. The protocol is event-based and optimized for low-latency streaming, making it viable for real-time agent interactions across web and mobile platforms. Generative UI typically means an LLM writes JSX or HTML, then the client renders it. This works for demos but creates three production problems: A2UI solves this by treating UI as data. The agent outputs a schema-validated stream of layout primitives. The client maps those primitives to native components. The agent never sees platform-specific rendering logic. The client never executes agent-generated code. This is the same separation used in server-driven UI frameworks like Litho or Epoxy, but extended to agent-generated content. A2UI uses an event-based protocol. The agent emits a stream of JSON events. Each event describes a UI operation: adding a component, updating state, or signaling completion. | Event Type | Purpose | Payload | |---|---|---| | component add | Append a component to the layout tree | Component type, props, parent ID | | component update | Modify existing component props | Component ID, updated props | | state sync | Synchronize application state | State key, value | | stream end | Signal completion of the UI stream | Optional metadata | The agent sends these events over HTTP streaming, WebSocket, or server-sent events. The client maintains a layout tree and applies events incrementally. JSONL format one JSON object per line : {"type": "component add", "id": "card-1", "component": "Card", "props": {"title": "Flight Options", "variant": "elevated"}, "parent": "root"} {"type": "component add", "id": "button-1", "component": "Button", "props": {"label": "Book Now", "action": "submit booking"}, "parent": "card-1"} {"type": "stream end"} The client receives these events, validates them against the component catalog schema, and renders them using the native framework adapter. The application defines a component catalog. This is a schema that lists available components and their props. The agent can only compose from this catalog. If the agent references an undefined component or passes invalid props, the client rejects the event. This enforces capability boundaries at the protocol level. The agent cannot: The catalog is versioned. Agents and clients negotiate protocol versions during handshake. This allows safe evolution of the component library without breaking existing agents. js const catalog = { components: { Card: { props: { title: { type: 'string', required: true }, variant: { type: 'enum', values: 'flat', 'elevated' } } }, Button: { props: { label: { type: 'string', required: true }, action: { type: 'string', required: true }, disabled: { type: 'boolean', default: false } } } } }; The agent SDK validates outgoing events against this schema before transmission. The client validates incoming events before rendering. Both sides reject invalid data. A2UI provides native adapters for React, Angular, Lit, Flutter, SwiftUI, and Jetpack Compose. Each adapter translates the protocol's layout data into platform-specific components. component add and component update events. The adapter maintains a mapping from A2UI component names to React components. When the agent emits a Button component, the adapter renders the application's