How it works
Your AI agent emits A2UI JSON
Any model or framework that returns structured JSON works: LangGraph, Google ADK, CrewAI, or a plain LLM call.
{ "type": "Form", "children": [ { "type": "TextField", "props": { "label": "Email", "isRequired": true } }, { "type": "Button", "props": { "variant": "primary", "children": "Subscribe" } } ] }
A2Renderer validates and resolves
Every node is parsed by its Zod schema before rendering. Invalid props are caught at the boundary, not silently ignored. The correct component is then looked up in your registry.
- Zod validation per node
- Registry lookup by type string
- Error boundary for unknown types
- Form-state and action wiring via
onAction
import { A2Renderer, createRegistry } from "@a2ra/core" import { Button } from "./a2ui/button" import { TextField } from "./a2ui/text-field" const registry = createRegistry({ Button: { component: Button }, TextField: { component: TextField }, }) <A2Renderer nodes={nodes} registry={registry} onAction={handleAction} />
Accessible React Aria components
Each component is a thin wrapper around React Aria. WCAG AA, keyboard navigation, and screen-reader support are built in. Source is copied into your project. You own every file.
An AI agent emits a JSON node describing intent. A2Renderer validates the node against
its Zod schema, looks up the matching component in your registry, and renders it as an
accessible React Aria component. The source for every component lives in your project,
so you own and can customise it freely.
See Agent Integration for connecting a real agent backend, or Building a Form Block for the full interactive form walkthrough.