Skip to content
On this page

Connecting an A2UI Renderer

Production setup sequence for maintained React, Lit, Angular, and Flutter A2UI renderers without assuming undocumented APIs.

Updated: 8/6/2026 Reviewed by: HIA2UI editorial team v0.9.1

Connecting an A2UI renderer

The host renderer validates messages, maintains Surface state, maps catalog entries to local components, and returns user actions. Transport is a separate layer.

1. Select the maintained renderer

HostMaintained package or SDK
React@a2ui/react with @a2ui/web_core
Web Components@a2ui/lit with @a2ui/web_core
Angular@a2ui/angular with @a2ui/web_core
FlutterFlutter GenUI packages documented by the official renderer guide

Install the version shown by the official renderer directory and pin it with the matching protocol schema. Public APIs can change between protocol lines, so copy initialization code from the installed package documentation rather than from an unversioned article.

2. Register a catalog

Map each allowed catalog entry to a host-owned component. Keep the catalog small, versioned, and explicit. A component that can navigate, embed remote content, read files, use the clipboard, authenticate, or commit a transaction needs a separate policy review.

// 1. Create a registry (The Firewall)
const catalog = createCatalog({ Text, Button, Form });

// 2. Render the output
const renderer = createRenderer({ catalog, protocolVersion: "0.9.1" });

The identifiers above illustrate responsibilities; use the exact exported API from your pinned renderer release.

3. Connect a framed stream

A2UI is transport-independent, but framing is not optional. Preserve complete message boundaries, limit size and rate, authenticate the peer, handle cancellation, and reject unsupported media types.

const response = await fetch("/api/agent", {
  headers: { Accept: "application/a2ui+json" },
});

// Feed chunks into A2UI parser
for await (const message of decodeA2UI(response.body)) {
  renderer.receive(validateA2UI(message));
}

4. Route actions through the server

renderer.onAction(async (action) => {
  // Action = { name: "submit", data: { ... } }
  await sendAuthorizedAction(action);
});

Never treat a visible or disabled component as authorization. Re-check identity, permissions, resource state, and idempotency on the server. Test invalid messages, unsupported components, partial streams, reconnects, stale actions, keyboard operation, and text fallback before release.

See the message reference, renderer matrix, and production checklist.