Series A announced

Read More
Copilot Kit Logo

CopilotKit - The Complete Frontend Stack for AI Agents

By Anmol Baranwal and Nathan Tarbert
May 20, 2026
CopilotKit - The Complete Frontend Stack for AI Agents

Every major software category is being rebuilt around agents. The question is no longer whether your product will have an AI agent, it's whether the interface around it is good enough for real users.

CopilotKit is the open-source frontend stack for AI agents. Used in production by the majority of the Fortune 500, and the team behind AG-UI - the open protocol for agent-user interaction, now adopted by Google, AWS, Microsoft, LangChain, Mastra, and more. We believe all UI is becoming AI.

CopilotKit gives you a complete developer toolkit to build, debug, and ship the interface layer between your agent and your users. Including chat components, hooks, persistent memory, generative UI, headless UI for custom agent interfaces, Inspector for debugging, and an MCP server for coding agent support. This guide covers all of that.

CopilotKit is open source with 30k+ stars on GitHub. Star the repo and come ship with us.

If you prefer watching, here's a quick overview of CopilotKit in under 3 minutes.

What is covered?

In a nutshell, we are covering these topics in detail.

  1. CopilotKit: building blocks for shipping Agent UIs
  2. Bring Agent to your app in 5 minutes
  3. Connecting your agent to a frontend (and when to use each)
    • Connect any LLM directly
    • Agent frameworks (13+ integrations)
    • Your own backend (custom logic, any server)
  4. Persistent memory across sessions and devices
  5. How to debug agents with the CopilotKit Inspector
  6. CopilotKit MCP server for Coding Agents
  7. Generative UI: build agents that ship their own interfaces.
  8. Headless UI: build fully custom agent interfaces
  9. VSCode Extension: preview, inspect, iterate on your agent UI
  10. Self-improving AI agents with continuous learning

That's a lot so let's get started. If you want to explore on your own, check the docs.

1. CopilotKit: building blocks for shipping Agent UIs

If every new agent capability requires a sprint of frontend changes, the agent isn't truly autonomous. It's just a backend API with a very expensive chat interface.

CopilotKit decouples the agent from the interface layer. Generative UI so the agent renders its own components. Shared state so the agent and UI stay in sync. Human-in-the-loop so users can approve before anything fires. All wired together through AG-UI, swap your agent backend tomorrow, and your frontend doesn't notice.

__wf_reserved_inherit

It's built in three layers:

✅ 1) Layer 1: Frontend (your app)

Hooks and components to wire up your app - registering tools agents can call, providing context, and getting agent instances.

✅ 2) Layer 2: Runtime (your server)

Receives requests from the frontend, runs agents, and streams events back. A few lines of setup, nothing to maintain. Handles everything between the model and the user.

✅ 3) Layer 3: Agent (any framework)

Anything that speaks AG-UI - the event protocol between agents and UIs (think: "text is streaming", "agent wants to call a tool", "state changed"). 13+ integrations or build your own.

The architecture guide in the repo covers how requests flow through all three layers, multi-agent patterns, and setup guides for React, Angular, Vue and vanilla JS.

__wf_reserved_inherit

Out of the box, you also get:

  • Persistent threads - conversations, state, and tool calls sync across devices and sessions. One hook to set it up.
  • Generative UI - instead of replying in text, the agent renders real components. Ask for your stats, it draws the chart. Ask to book a flight, the booking form appears.
  • MCP server for coding agents - point your coding agent at it for live access to the right docs and snippets. No stale training data, no usage limit.
  • Agent Inspector - in-browser panel for debugging actions, readables, agent status, messages, and context.
  • VSCode extension - the same inspector view inside your editor, plus live preview of your agent-rendered components without running the full app.

We have covered each of these in-depth below.

__wf_reserved_inherit

2. Bring Agent to your app in 5 minutes.

The fastest way to bring CopilotKit to your app is by using the CLI. If you are starting from scratch, run this command:

// scaffolds a new full-stack app
npx copilotkit@latest create
__wf_reserved_inherit

To add CopilotKit to an existing project, run this command to pick your agent framework:

// adds CopilotKit to an existing project
npx copilotkit@latest init
__wf_reserved_inherit

Both leave you with packages installed, provider configured, a runtime endpoint ready, and a chat component on screen. Check the quickstart docs for every integration.

__wf_reserved_inherit

Once you're set up, you can experiment with hooks and components. Here are the useful ones to give your agent context and let it take actions.

useAgentContext makes your app's state visible to the agent, whatever you pass in becomes part of the LLM's context - current user, selected items, loaded data. The agent knows what your app knows.

useFrontendTool exposes any function in your app as a tool the agent can call. You describe what it does, the agent decides when to use it based on that description, calls it when relevant, and your UI updates. The model never touches your state directly:

// ... useAgentContext

useFrontendTool({
  name: "addExpense",
  description: "Add a new expense when the user mentions spending money on something.",
  parameters: z.object({
    description: z.string().describe("What the expense was for, e.g. Lunch, Taxi, Coffee"),
    amount: z.number().describe("How much was spent in dollars"),
    category: z.string().describe("Food, Transport, Entertainment, Health, or Other"),
  }),
  handler: async ({ description, amount, category }) => {
    setExpenses((prev) => [
      ...prev,
      { id: Date.now(), description, amount, category },
    ]);
    return `Added $${amount} for ${description}`;
  },
  // optional: render the component in chat while/after the tool runs
  render: ({ status, args }) => (
    <ExpenseCard
      status={status}
      description={args.description}
      amount={args.amount}
      category={args.category}
    />
  ),
});
__wf_reserved_inherit

useAgent gives you a live connection to your agent - its messages, current state, and whether it's running. Read it or update it directly from your UI:

// Programmatically access and control your agents
const { agent } = useAgent({ agentId: "my_agent" });

// Render and update your agent's state
return <div>
  <h1>{agent.state.city}</h1>
  <button onClick={() => agent.setState({ city: "NYC" })}>
    Set City
  </button>
</div>
__wf_reserved_inherit

These three cover the basics. There are many:

  • built-in chat components like CopilotChat, CopilotSidebar, CopilotPopup, CopilotChatView.
  • hooks depending on what you're building: useHumanInTheLoop for approval flows, useComponent for generative UI, useThreads for persistence.

Full list in the v2 API reference.

For a deeper walkthrough covering setup, giving the AI context, and letting it take actions, check out How to add AI to your app in 5 minutes.

File and image attachments.

Real users don't just type. You can also let users send images, audio, video, and documents to the agent alongside their messages. One prop to enable it:

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

<CopilotChat
  agentId="my-agent"
  attachments={{ enabled: true }}
/>

Users can click the attachment button or drag and drop files. Works with the Built-in Agent, any supported framework, or your own backend.

__wf_reserved_inherit
__wf_reserved_inherit

Not all models support all file types, so use the onError callback to handle unsupported cases gracefully. Read more on the docs.

3. Connecting your agent to a frontend (and when to use each)

Now that you have a working app, you have a choice about what runs behind the runtime. You don't always need a full agent framework - it depends on what you're building and what you already have.

The key thing to know: every agent speaks AG-UI, the open bi-directional protocol for agent-user interaction. That means your frontend never changes, regardless of what's running behind it.

Swap the Built-in Agent for LangGraph tomorrow and your <CopilotChat />, hooks, and components stay exactly the same.

__wf_reserved_inherit

There are three ways to connect. Pick based on what you already have.

Path 1: Connect any LLM directly

No framework needed. If you just want an agent that's aware of your app and can take actions in it, the BuiltInAgent is all you need.

The runtime handles the model call, tool loop, and streaming. Everything lives in one endpoint at app/api/copilotkit/route.ts:

import {
  CopilotRuntime,
  copilotRuntimeNextJSAppRouterEndpoint,
} from "@copilotkit/runtime";
import { BuiltInAgent } from "@copilotkit/runtime/v2"; 
import { NextRequest } from "next/server";

const runtime = new CopilotRuntime({
  agents: new BuiltInAgent({ model: "openai/gpt-5.5" }),
});

export const POST = async (req: NextRequest) => {
  const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
    runtime,
    endpoint: "/api/copilotkit",
  });
  return handleRequest(req);
};

If you want to switch to any other LLM Provider, you just need to pass the modified string to BuiltInAgent in your API route. Everything else remains the same.

// Anthropic
const builtInAgent = new BuiltInAgent({ model: "anthropic:claude-opus-4-6" });

// Google
const builtInAgent = new BuiltInAgent({ model: "google/gemini-2.5-pro" });

Add the matching key to .env.local and you are done. For custom models like Azure OpenAI, AWS Bedrock or Ollama, check the model selection docs.

Reasoning models like openai:o3 and openai:o4-mini work too, pass reasoningEffort to control how hard the model thinks. For Anthropic extended thinking, use budgetTokens. The reasoning stream renders directly in the chat UI.

// Anthropic with extended thinking
const agent = new BuiltInAgent({
  model: "anthropic:claude-sonnet-4-6",
  providerOptions: {
    anthropic: { thinking: { type: "enabled", budgetTokens: 10000 } },
  },
});

Read more in the advanced configuration docs.

Good for solo devs, in-app assistants, chatbots, and prototypes. You can also use MCP Apps middleware on top of this to return interactive MCP Apps (forms, canvases, pickers) right in chat.

const agent = new BuiltInAgent({
  model: "openai/gpt-5.5",
  prompt: "You are a helpful assistant.",
}).use(
// describe a diagram in chat, Excalidraw MCP server returns an interactive UI
  new MCPAppsMiddleware({
    mcpServers: [
      { type: "http", url: "https://mcp.excalidraw.com/mcp", serverId: "excalidraw" },
    ],
  }),
);

Path 2: Agent frameworks

CopilotKit ships first-party integrations for 13+ agent frameworks through AG-UI - the open protocol that connects any agent to any frontend.

If you already have an agent running any framework, just point the runtime at your agent's endpoint using HttpAgent:

import {
  CopilotRuntime,
  ExperimentalEmptyAdapter,
  copilotRuntimeNextJSAppRouterEndpoint,
} from "@copilotkit/runtime";
import { HttpAgent } from "@ag-ui/client";
import { NextRequest } from "next/server";

const serviceAdapter = new ExperimentalEmptyAdapter();

const runtime = new CopilotRuntime({
  agents: {
    my_agent: new HttpAgent({ url: "http://localhost:8000/" }),
  }
});

export const POST = async (req: NextRequest) => {
  const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
    runtime,
    serviceAdapter,
    endpoint: "/api/copilotkit",
  });

  return handleRequest(req);
};

The pattern is the same across all of them: your agent emits events over AG-UI, the CopilotKit runtime speaks AG-UI on the other end, and your tools, shared state, and approval flows surface in the UI automatically. No extra glue code.

Supported: LangGraph, TanStack, Mastra, Pydantic AI, CrewAI, Microsoft Agent Framework, Google ADK, AWS Strands, LlamaIndex, Agno, AG2, Deep Agents, Open Agent Spec (agent-spec), A2A, and more. Each has a dedicated quickstart in the docs.

Good for teams with complex workflows, multi-agent orchestration, or an existing agent they want to keep.

Path 3: Your own backend (custom logic, any server)

If you have existing AI infrastructure like an internal LLM proxy, a fine-tuned model endpoint, or custom tool dispatch, you can run CopilotRuntime on your own server.

CopilotKit handles the protocol layer between your backend and the frontend without requiring an agent framework.

import express from "express";
import { CopilotRuntime, BuiltInAgent } from "@copilotkit/runtime/v2";
import { createCopilotExpressHandler } from "@copilotkit/runtime/v2/express";

const runtime = new CopilotRuntime({
  agents: {
    default: new BuiltInAgent({ model: "openai/gpt-5" }),
  },
});

const app = express();

// Mount the CopilotKit router — creates Express routes under /api/copilotkit
app.use(
  createCopilotExpressHandler({
    runtime,
    basePath: "/api/copilotkit",
    cors: true,
  }),
);

Once your runtime is running, point your frontend at it:

<CopilotKit runtimeUrl="http://localhost:4000/api/copilotkit">
  <YourApp />
</CopilotKit>

Works with Next.js, Express, Hono, Bun, Deno, Cloudflare Workers, React Router, TanStack Start, Elysia, and more. Full setup in the runtime server adapter docs.

Good for teams with existing AI services, custom infrastructure, or specific deployment requirements where you need full control over the server layer.

__wf_reserved_inherit

4. Persistent memory across sessions and devices

Most agents start from zero every time. The user closes the tab, comes back tomorrow, and the agent has no idea what they were working on. Fine for a demo. A real blocker for anything running in production, where users come back, switch devices, and expect the conversation to be exactly where they left it.

Without threads, every agent session ends with the tab that ran it. With threads, the run becomes part of your application's state.

One hook gives you a full ChatGPT-style thread sidebar with persistent memory:

const {
  threads,
  renameThread,
  archiveThread,
  deleteThread,
  hasMoreThreads,
  fetchMoreThreads,
} = useThreads();
__wf_reserved_inherit

Threads work a little differently in CopilotKit. Runs live on the server and streams over AG-UI, so you can step away from the agent anytime.

Return later on a different device and you will see the run exactly where the agent is in that moment, still actively progressing.

It holds everything that happens between the user, the agent, and the app.

__wf_reserved_inherit

5. How to debug agents with the CopilotKit Inspector

Agents are a black box. You write the code, run it, and hope it behaves. When something goes wrong, there's no stack trace, just a user getting a weird response and zero visibility into what actually happened.

The CopilotKit Inspector is a built-in debugging tool that overlays on your app, giving you full visibility into what's happening between your frontend and your agents in real time:

  • raw AG-UI event stream
  • which agents are connected and available
  • agent state as it updates
  • frontend tools you've defined and their parameter schemas
  • full context provided to the agent, including readables and document context

Enabled by default in development. To disable it:

<CopilotKit
  showDevConsole={false}
>
  {children}
</CopilotKit>

When you open the Inspector, threads are the default tab. Sign up for the free Developer tier to see your conversation history.

6. CopilotKit MCP Server for coding agents (Claude Code, Codex, Cursor)

If you're building with a coding agent like Claude Code, Cursor, or Windsurf, there's one more thing worth setting up before you write a line of CopilotKit code.

Coding agents usually default to whatever knowledge was in their training data, which could be months stale - deprecated hooks mentioned in old tutorials, patterns that no longer work. Context matters a lot when you are using agentic tools.

CopilotKit ships a knowledge MCP server at mcp.copilotkit.ai/mcp. Connect your coding agent to it and it gets live access to the right API signatures, accurate code examples, and implementation patterns. Free, no usage limit.

For Claude Code, run this in your terminal:

claude mcp add --transport http copilotkit-mcp https://mcp.copilotkit.ai/mcp
__wf_reserved_inherit

As you can see, Claude fetched the exact hook signatures just by name. This also keeps your context fresh and makes sure you are always building with the latest stable hooks.

__wf_reserved_inherit

For Cursor, Claude Web, Claude Desktop, Windsurf, Cline, Codex, GitHub Copilot and others, refer to the Coding Agents docs.

If your tool doesn't support MCP, drop this into your model's context directly:

https://mcp.copilotkit.ai/llms.txt

7. Generative UI: build agents that ship their own interfaces.

You've felt this before. You ask an AI to compare three options and you get a wall of text when you wanted a table. You ask for a calendar and you get prose describing one. The model isn't the problem. It can render the table. It just doesn't know it's allowed to.

Generative UI is the layer that lets agents stop describing and start showing.

__wf_reserved_inherit

Three patterns have emerged. The spectrum runs from more control to more flexibility. CopilotKit ships support for all three. You can try all the examples live.

If you prefer watching, the DeepLearning.AI course covers everything: Build Interactive Agents with Generative UI.

__wf_reserved_inherit

Controlled - you pre-build the components, the agent picks which one to show and fills it with data. Ask for your spending breakdown, the agent calls pieChart and streams the data into it. Your design system, pixel-perfect. The hook is useComponent.

The catch: every component you register is a tool definition in the agent's context. Past 25, the agent starts guessing. Pie chart and donut chart both "show proportions." It picks wrong.

Example: "Show me our revenue distribution by category" -- the agent fetches the data and renders your pieChart component inline.

__wf_reserved_inherit

Declarative (A2UI) - instead of pre-building every component, you give the agent a schema and it figures out the layout. One tool, many UIs, flat token cost as your library grows. Add a new card type, and the agent can use it immediately. Built on Google's A2UI protocol.

The catch: the LLM owns the layout. Output varies run to run. Not for legal disclosures, marketing surfaces, or anything where exact pixel placement matters.

Example: "Find flights from SFO to JFK for next Tuesday" -- the agent composes flight cards. Click a flight, and the agent receives the selection.

__wf_reserved_inherit

Open-ended (MCP Apps / Open Generative UI) - the agent writes raw HTML, your app renders it in a sandboxed iframe. No catalog, no schema, no rules.

Good for throwaway - "show me how electrons work", "give me a weird bar chart of my last 10 queries." Not for anything a real user sees twice.

Example: "Build a neo-brutalism themed calculator" -- the agent generates the full interactive HTML on the spot.

__wf_reserved_inherit

If you are interested in reading more about the tradeoffs with complete code, check out these blogs:

8. Headless UI: build fully custom agent interfaces

The prebuilt components CopilotChat, CopilotSidebar, CopilotPopup cover most cases. But not every product should have a floating chat bubble.

Sometimes the agent needs to live inside your dashboard, respond through a voice interface, or narrate its progress in a sidebar that matches your product so well users don't know it's an AI feature.

If you just need to tweak the layout or style of the prebuilt components, the slot system is the easier path.

Headless UI is for when you need to go further - a completely different layout, a non-chat interface, or something embedded deep in your existing UI.

Here are the two primitives everything is built on:

  • useAgent gives you the messages, state, and run status.
  • useCopilotKit gives you copilotkit.runAgent() to trigger the agent from anywhere:
import { useAgent, useCopilotKit } from "@copilotkit/react-core/v2";

export default function Chat() {
  const { agent } = useAgent();
  const { copilotkit } = useCopilotKit();

  return (
    <div>
      {agent.messages.map(m => (
        <p key={m.id}>{m.content}</p>
      ))}
      <button onClick={() => copilotkit.runAgent({ agent })}>
        {agent.isRunning ? "Thinking..." : "Send"}
      </button>
    </div>
  );
}
__wf_reserved_inherit

Read more on the docs.

9. VSCode Extension: preview, inspect, iterate on your agent UI

The CopilotKit VSCode extension brings four tools into your editor so you can iterate without running the full app.

Hook Explorer (Generative UI) - scans your workspace for CopilotKit hooks, renders their generative UI with auto-generated form controls. Offline, no agent run needed.

A2UI Catalog Preview - live preview your catalog components. Edit the file, save, and the preview hot-reloads instantly.

Playground - full chat surface that actually runs your agent inside the editor. Detects your hooks, wires them to a local runtime, and hot-reloads on save.

AG-UI Inspector - shows a real-time stream of every AG-UI event your runtime emits, color-coded and filterable.

You can install it from VSCode Marketplace or from the terminal. Read more on the docs.

code --install-extension copilotkit.copilotkit

10. Self-improving agents with continuous learning

Right now, agents stay exactly as smart as the day you shipped them. If the agent makes the same mistake every time a user tries to export a CSV, it keeps making that mistake until you notice, trace it back, patch the prompt, and redeploy.

Every user-agent interaction flows through AG-UI as typed events. Accepted answers, edited responses, re-run tools, ignored suggestions - all of it is captured. The thread layer makes that data persistent. That's a labeled feedback stream sitting right there.

These are part of the CopilotKit Intelligence Platform.

Analytics & Insights - see how your agent is performing in production. Which flows are working, where users are dropping off, and what's getting ignored. SQL-queryable data for compliance and audit. Connects to DataDog, New Relic, or whatever you already use.

Continuous Learning from Human Feedback (CLHF) - signals from real usage feed back into the agent. Prompts adapt at runtime, per user and per context, based on recent outcomes. The agent keeps getting better the more it's used.

This is what Cursor did to build their Composer model. Every developer interaction was implicit training data. CopilotKit is bringing that loop to your app, on top of AG-UI.

Both are in active development. Sign up for early access.

__wf_reserved_inherit

Conclusion

CopilotKit is the layer between your agent and your users.

The hard part of agent products isn't the model - it's the interface that makes it usable, stateful, and safe for real people. That's the problem we exist to solve, and everything in this guide is built around it.

The use cases are wide open. SaaS copilots, productivity tools, customer support agents, internal dashboards, and generative UI experiences nobody has built yet. Whatever you're shipping, the docs have everything you need.

If you get stuck, reach out to us in the CopilotKit or AG-UI communities.

Want to bring CopilotKit into your stack? Book a call with our engineers.

Happy building!

Are you ready?

Stay in the know

Subscribe to our blog and get updates on CopilotKit in your inbox.