Custom components let you surface your own design system widgets — charts, maps, media players, or any proprietary UI element — inside A2UI without changing the protocol. Agents interact with your component through a JSON schema you define; your framework code decides how that schema is rendered. This guide walks through all four steps of the authoring lifecycle using theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/a2ui-project/a2ui/llms.txt
Use this file to discover all available pages before exploring further.
rizzcharts community sample as a concrete example.
What is a “Smart Wrapper”?
A Smart Wrapper is a framework component that sits between the raw A2UI JSON payload and your underlying widget library. It receives typed, data-bound props resolved from the agent’s data model, and it exposes anaction callback that the Generic Binder wires to the agent automatically. You author the schema, the framework class extends a base provided by the renderer package (e.g. DynamicComponent in Angular, A2uiLitElement in Lit), and the renderer handles all the binding plumbing.
Use a Smart Wrapper when:
- You want data-binding: a property value should be read from the agent’s live data model via
{ "path": "/some/key" }rather than inlined as a literal. - You want two-way binding: your component can mutate the data model and the agent should observe the updated value.
- You want validation: your component should call catalog-defined check functions and surface
isValid/validationErrorsto the agent before dispatching an action.
createBinderlessComponentImplementation or equivalent) only when you need direct access to the raw ComponentModel — for example, a developer inspector or a performance-critical animation that manages its own reactivity.
Step 1: Define the catalog schema
The catalog schema is the API contract between the client and the agent. The agent uses it to construct valid UI payloads; the client uses it to validate incoming messages. Both sides must agree on the same schema — the client advertises which catalog IDs it supports and the agent selects a compatible one during the capability handshake. Define each component as a named object under a top-levelcomponents key in a JSON Schema file. The rizzcharts sample stores its schema at catalog_schemas/0.9/rizzcharts_catalog_definition.json. Here is the Chart component entry:
Properties that accept either a literal value or a data model path follow the A2UI bound-value pattern: an object with either a
literalString / literalArray key or a path key. The renderer’s binding layer resolves these transparently before your component code runs.CommonSchemas from @a2ui/web_core/v0_9, which gives you compile-time safety and automatic two-way binding inference:
Step 2: Implement the component
Implement the UI using your framework of choice. The key contract is: your component receives already-resolved, typed props — not raw JSON — because the renderer’s binding layer has already walked the data model. Therizzcharts Angular implementation extends DynamicComponent from @a2ui/angular, which wires resolvePrimitive for any property that uses the bound-value shape:
createComponentImplementation with a Zod schema, and in Lit you extend A2uiLitElement and return an A2uiController. In all three cases the framework-specific boilerplate is minimal — web_core does the data-binding work.
Key implementation rules:
- Always extend the renderer base class (
DynamicComponent,A2uiLitElement, etc.) — this gives youresolvePrimitiveand automatic reactive updates when the data model changes. - Map schema properties directly to framework inputs — one input per schema property, typed to match the schema’s bound-value shape.
- Never fetch or mutate external state directly from a component — communicate back to the agent only through A2UI
actionprimitives so the session state stays consistent.
Step 3: Register the component in a catalog
Once implemented, register your component by composing it into aCatalog object alongside the default catalog. This maps the string name used by agents to your class and its input bindings.
- Angular
- React
- Lit
Step 4: Invoke from the agent
The agent side uses the A2UI Python SDK to resolve the catalog, inject examples into the model’s context, and callsend_a2ui_json_to_client with a payload that references your component by name.
4.1 Session preparation
The executor intercepts the incoming message, detects whether A2UI is enabled, resolves the catalog that the client advertised, and stores the schema and examples in session state:4.2 Attach the toolset to the agent
SendA2uiToClientToolset exposes a send_a2ui_json_to_client tool that the LLM can call to emit A2UI payloads:
4.3 Wire the event converter
Tool calls made by the LLM are intercepted by theA2uiEventConverter, which translates them into A2A DataParts carrying the A2UI payload — no manual JSON construction required:
Security considerations
The following section describes threats that apply to all custom component authors, not just the
rizzcharts sample. Review it before shipping any catalog to production.path value or literal string containing script fragments. Never pass agent-supplied strings directly to innerHTML, dangerouslySetInnerHTML, or equivalent APIs. Use your framework’s text interpolation (which auto-escapes) or a well-maintained sanitization library.
Phishing / UI spoofing — A malicious agent could render components that mimic login dialogs or payment forms. Validate that the catalogId presented in createSurface matches the one your client registered. Do not render components whose catalogId you did not explicitly trust.
Denial of service (DoS) — Agents can send deeply nested component trees or large data models. Apply reasonable limits on tree depth, component count per surface, and data model size at the MessageProcessor layer before the data reaches your components.
Embedded content — If any component renders an <iframe> or web view, apply a strict sandbox attribute and a Content-Security-Policy that blocks navigation and script execution from the embedded origin.
Developer responsibility — A2UI renderers do not apply any sanitization on your behalf. Input validation, CSP headers, credential isolation, and sandboxing are your responsibility as the component author.
Further reading
Renderer Development
Build a new A2UI renderer for a web framework or non-web platform from scratch.
Catalog Reference
Full specification of the catalog negotiation protocol and catalog schema format.
Data Binding Reference
Path resolution rules, scope, template lists, and two-way binding semantics.
rizzcharts sample
Complete end-to-end example: schema, Angular component, catalog registration, and Python executor.