Skip to content
Development
Skill

/a2ui-renderer

Render A2UI (Agent-to-UI declarative surfaces) in CopilotKit v2. Enable the runtime via CopilotRuntime({ a2ui: {...} }), then enable the provider via <CopilotKit a2ui={{ theme }}>. Auto-activates via /info — do NOT manually pass renderActivityMessages. createA2UIMessageRenderer

From plugin
copilotkit
37k17 skills2 MCP
Install
$ npx -y skills add CopilotKit/CopilotKit --skill a2ui-renderer --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/a2ui-renderer

Context preview

The summary Claude sees to decide when to auto-load this skill.

Render A2UI (Agent-to-UI declarative surfaces) in CopilotKit v2. Enable the runtime via CopilotRuntime({ a2ui: {...} }), then enable the provider via <CopilotKit a2ui={{ theme }}>. Auto-activates via /info — do NOT manually pass renderActivityMessages. createA2UIMessageRenderer

SKILL.md

a2ui-renderer.SKILL.md
name: a2ui-renderer
description: >
  Render A2UI (Agent-to-UI declarative surfaces) in CopilotKit v2. Enable the
  runtime via CopilotRuntime({ a2ui: {...} }), then enable the provider via
  <CopilotKit a2ui={{ theme }}>. Auto-activates via /info — do NOT
  manually pass renderActivityMessages. createA2UIMessageRenderer ships from
  @copilotkit/react-core/v2; low-level primitives (A2UIProvider, A2UIRenderer,
  createCatalog) ship from @copilotkit/a2ui-renderer. Covers theme
  customization, createSurface dedup, action-bridge try/finally cleanup. Load
  when an agent emits A2UI operations (createSurface / updateComponents /
  updateDataModel), when wiring a2ui on CopilotRuntime, or when styling A2UI
  surfaces.
type: framework
library: copilotkit
framework: react
library_version: "1.56.2"
requires:
  - copilotkit/react-core
  - copilotkit/runtime
sources:
  - "CopilotKit/CopilotKit:packages/a2ui-renderer/src/index.ts"
  - "CopilotKit/CopilotKit:packages/a2ui-renderer/src/react-renderer/index.ts"
  - "CopilotKit/CopilotKit:packages/react-core/src/v2/a2ui/A2UIMessageRenderer.tsx"
  - "CopilotKit/CopilotKit:packages/react-core/src/v2/providers/CopilotKitProvider.tsx"
  - "CopilotKit/CopilotKit:packages/runtime/src/v2/runtime/core/runtime.ts"

This skill builds on copilotkit/react-core (for `CopilotKit` provider fundamentals) and copilotkit/runtime (for CopilotRuntime fundamentals). Read those first.

Setup

A2UI has two halves. The runtime declares a2ui middleware; the client enables the a2ui prop on the provider. Once both are set, `/info` flags A2UI and the client auto-mounts `createA2UIMessageRenderer` — you do NOT wire `renderActivityMessages` yourself.

Runtime side (`app/routes/api.copilotkit.$.tsx`)

import type { Route } from "./+types/api.copilotkit.$";
import {
  CopilotRuntime,
  createCopilotRuntimeHandler,
  BuiltInAgent,
  convertInputToTanStackAI,
} from "@copilotkit/runtime/v2";
import { chat } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";

const agent = new BuiltInAgent({
  type: "tanstack",
  factory: ({ input, abortController }) => {
    const { messages, systemPrompts } = convertInputToTanStackAI(input);
    return chat({
      adapter: openaiText("gpt-4o"),
      messages,
      systemPrompts,
      abortController,
    });
  },
});

const runtime = new CopilotRuntime({
  agents: { default: agent },
  // Enabling this key causes /info to advertise A2UI to the client.
  a2ui: {},
});

const handler = createCopilotRuntimeHandler({
  runtime,
  basePath: "/api/copilotkit",
});

export async function loader({ request }: Route.LoaderArgs) {
  return handler(request);
}
export async function action({ request }: Route.ActionArgs) {
  return handler(request);
}

Client side (`app/root.tsx` or the app shell)

import { CopilotKit, CopilotChat } from "@copilotkit/react-core/v2";
import "@copilotkit/react-core/v2/styles.css";

export default function App() {
  return (
    <CopilotKit
      runtimeUrl="/api/copilotkit"
      a2ui={{
        theme: {
          // Theme object forwarded to A2UIProvider → ThemeProvider.
          // Tokens map to A2UI's basic catalog CSS vars.
          colors: { primary: "#0ea5e9" },
        },
      }}
    >
      <CopilotChat agentId="default" className="h-full" />
    </CopilotKit>
  );
}

Core Patterns

Custom catalog

Pass a custom catalog to extend the built-in component set. `createCatalog` and `extractSchema` let the agent see what components it may render.

import { createCatalog } from "@copilotkit/a2ui-renderer";
import { z } from "zod";

const theme = { colors: { primary: "#0ea5e9" } };

// Definitions are platform-agnostic (Zod schemas + descriptions).
// Renderers are platform-specific (React components).
// TypeScript enforces that renderer keys match definition keys exactly.
const definitions = {
  ProductCard: {
    description: "A product card with title and price",
    props: z.object({ title: z.string(), price: z.number() }),
  },
};

const catalog = createCatalog(
  definitions,
  {
    ProductCard: ({ props }) => (
      <div className="rounded-xl border p-3">
        <div className="font-medium">{props.title}</div>
        <div className="text-sm text-muted-foreground">${props.price}</div>
      </div>
    ),
  },
  { includeBasicCatalog: true },
);

<CopilotKit runtimeUrl="/api/copilotkit" a2ui={{ theme, catalog }}>
  <CopilotChat agentId="default" />
</CopilotKit>;

`extractSchema(definitions)` is available for passing a JSON-serializable view of the definitions to the runtime's `a2ui.schema` config — it is not a generic type helper. Type parameters erase at runtime; the agent needs a real runtime schema value (Zod).

Override the loading skeleton

<CopilotKit
  runtimeUrl="/api/copilotkit"
  a2ui={{
    theme,
    loadingComponent: () => <div className="animate-pulse">Building UI…</div>,
  }}
>
  <CopilotChat agentId="default" />
</CopilotKit>

Common Mistakes

CRITICAL forgetting runtime.a2ui

Wrong:

// server
new CopilotRuntime({ agents: { default: agent } });
// client
<CopilotKit runtimeUrl="/api/copilotkit" a2ui={{ theme }} />;

Correct:

// server
new CopilotRuntime({ agents: { default: agent }, a2ui: {} });
// client
<CopilotKit runtimeUrl="/api/copilotkit" a2ui={{ theme }} />;

Without `runtime.a2ui`, `/info` never flags A2UI and the provider's a2ui prop silently no-ops — the renderer never mounts.

Source: packages/runtime/src/v2/runtime/core/runtime.ts:55-58,217,242

HIGH manually wiring renderActivityMessages for A2UI

Wrong:

import { createA2UIMessageRenderer } from "@copilotkit/react-core/v2";

<CopilotKit
  runtimeUrl="/api/copilotkit"
  renderActivityMessages={[createA2UIMessageRenderer({ theme })]}
/>;

Correct:

<CopilotKit runtimeUrl="/api/copilotkit" a2ui={{ theme }} />

The `CopilotKit` provider auto-detects runtime A2UI via `/info` and injects the buil

Read more
Ships withcopilotkit

Docs · Examples · Enterprise Intelligence Platform · Build agent-native applications — on any framework, on any surface. Generative UI, shared state, and human-in-the-loop workflows for React, Angular, Vue, React Native — and beyond the browser.

Get the whole plugin

Other skills on copilotkit.