How to Integrate A2UI with Existing Applications: A Complete Developer Guide

Integrate A2UI by installing the framework-specific renderer and shared @a2ui/web-lib, initializing a MessageProcessor to manage state, rendering a surface component bound to that processor, and connecting to an agent via A2UIClient to exchange JSON payloads that dynamically update your UI.

A2UI is an open-source framework from Google that enables AI agents to generate dynamic user interfaces through JSON payloads rather than executable code. If you are looking to integrate A2UI with existing applications, you will bridge your current frontend stack with the A2UI architecture using framework-specific renderers and the core message processing library. This guide walks through the exact implementation steps, source file references, and code patterns used in the google/A2UI repository.

Understanding the A2UI Integration Architecture

Before writing code, understand how A2UI separates UI generation from rendering. The architecture consists of five distinct layers:

  1. Agent — Generates A2UI JSON payloads describing component hierarchies and data models.
  2. Transport — Delivers payloads via Server-Sent Events (SSE), WebSockets, or the A2A protocol.
  3. MessageProcessor — The core state machine in @a2ui/web-lib that validates ServerToClientMessage instances and updates an in-memory surface model tracking surfaces, catalogs, component models, and the data model.
  4. Renderer — Framework-specific packages (Lit, React, Angular, Flutter) that map abstract components to native widgets.
  5. User Interaction — Captured as A2UI action events and forwarded back to the agent.

Core Components and Source Locations

Component Role Source Location
MessageProcessor Validates and applies incoming messages, manages surfaces and data models. renderers/web_core/src/v0_9/processing/message-processor.ts
A2UIClient Thin wrapper around the A2A JavaScript SDK handling MIME types and message extraction. samples/client/lit/shell/client.ts
Web Library Shared core library for state management across all web renderers. @a2ui/web-lib
Agent SDK Python utilities for generating valid A2UI payloads. agent_sdks/python/README.md
Catalog Definitions Component definitions the client renders. specification/v0_9/json/catalogs/minimal/README.md

Step-by-Step A2UI Integration Guide

Follow these eight steps to embed A2UI into an existing web application. These steps assume a Lit-based integration, but the patterns apply to React and Angular with minor syntax adjustments.

1. Select and Install Your Renderer

Choose the package matching your frontend framework. All web renderers depend on @a2ui/web-lib for core functionality.

npm install @a2ui/web-lib lit @lit-labs/signals

2. Initialize the Message Processor

Create a processor instance to hold surfaces and manage data models. In renderers/web_core/src/v0_9/processing/message-processor.ts, the MessageProcessor class implements the validation and state update logic.

import { v0_8 } from "@a2ui/lit";

// Create a signal-based processor (v0.8 API)
const processor = v0_8.Data.createSignalA2uiMessageProcessor();

3. Render the Surface Component

Insert the framework-specific surface component and bind the processor. The surface acts as a canvas for dynamically generated UI.

For Lit:

import { html } from "lit";
import "@a2ui/lit/ui/surface.js";

export const MyApp = html`
  <a2ui-surface .processor=${processor}></a2ui-surface>
`;

4. Establish Agent Connection via A2UIClient

Instantiate A2UIClient from samples/client/lit/shell/client.ts with your agent's base URL. The client automatically injects the required A2A-extension header https://a2ui.org/a2a-extension/a2ui/v0.8.

import { A2UIClient } from "./client.js";

const a2uiClient = new A2UIClient("http://localhost:10002");

5. Send User Messages to the Agent

When users submit input, construct an A2UIClientEventMessage and transmit it via A2UIClient.send().

async function sendUserMessage(text: string) {
  const msg: v0_8.Types.A2UIClientEventMessage = {
    userAction: {
      name: "userMessage",
      surfaceId: "default",
      sourceComponentId: "chatInput",
      timestamp: new Date().toISOString(),
      context: { text },
    },
  };
  const responses = await a2uiClient.send(msg);
  processor.processMessages(responses);
}

6. Process Agent Responses

Pass returned ServerToClientMessage[] arrays to processor.processMessages(). This updates component trees and mutates the data model, triggering automatic UI re-renders via framework-specific signals or observables.

7. Handle Component Actions

Listen for user interaction events emitted by rendered components. In Lit, use the @a2uiaction event; React uses onA2uiAction.

render() {
  return html`
    <a2ui-surface
      @a2uiaction=${async (e: CustomEvent) => {
        const { name, surfaceId, sourceComponentId, context } = e.detail.action;
        const msg: v0_8.Types.A2UIClientEventMessage = {
          userAction: {
            name,
            surfaceId,
            sourceComponentId,
            timestamp: new Date().toISOString(),
            context,
          },
        };
        const responses = await a2uiClient.send(msg);
        processor.processMessages(responses);
      }}
      .processor=${processor}
    ></a2ui-surface>
  `;
}

8. Complete the Round-Trip

This configuration creates a full agent-to-UI-to-agent loop: the agent generates JSON UI descriptions, the client renders them, user actions generate events, and the agent responds with incremental updates without shipping executable code.

Reference Implementation and Key Files

Study these source files in the google/A2UI repository to see production-ready integration patterns:

Summary

  • A2UI integration requires separating UI generation (agent) from rendering (client) using JSON payloads transported over SSE, WebSockets, or A2A.
  • Install the framework-specific renderer plus @a2ui/web-lib to access shared state management.
  • Initialize a MessageProcessor (from renderers/web_core/src/v0_9/processing/message-processor.ts) to validate and apply ServerToClientMessage updates.
  • Bind the processor to a surface component (<a2ui-surface> in Lit) to render dynamic UI.
  • Connect to agents using A2UIClient, which handles the https://a2ui.org/a2a-extension/a2ui/v0.8 header and MIME type wrapping.
  • Handle user actions by listening for renderer events, forwarding them to the agent, and processing subsequent UI updates.

Frequently Asked Questions

What frontend frameworks does A2UI support?

A2UI provides official renderers for Lit, React, Angular, and Flutter. All web renderers share the core @a2ui/web-lib package and differ only in their thin rendering layers that map abstract components to framework-native widgets.

How does the MessageProcessor manage state updates?

The MessageProcessor class maintains an in-memory surface model containing surfaces, catalogs, component models, and a JSON-pointer-addressable data model. When processMessages() receives a ServerToClientMessage array, it validates the messages, creates or deletes surfaces, updates component trees, and mutates the data model, automatically triggering UI re-renders through the bound framework's reactivity system.

Can I use A2UI without the A2A protocol?

Yes. While A2UIClient simplifies A2A integration, the transport layer supports Server-Sent Events (SSE) and WebSockets directly. You can implement a custom transport adapter that conforms to the message format expected by MessageProcessor without using the A2A JavaScript SDK.

Where is the agent-side logic implemented?

The A2UI Agent SDK (Python) located in agent_sdks/python/README.md provides helper utilities for generating valid A2UI payloads, managing component catalogs, and embedding the required A2A-extension header in HTTP requests.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →