AI/TLDR

What Is CopilotKit? In-App Copilots & Generative UI

You will understand what CopilotKit provides for building in-app copilots and generative UI in React or Angular, and how it relates to the AG-UI protocol.

INTERMEDIATE10 MIN READUPDATED 2026-06-14

In plain English

Imagine you want to add an AI assistant inside your app — not a separate chat website, but a helper that lives in the corner of your dashboard, sees what the user is looking at, and can actually do things: filter a table, fill a form, draft an email, open a record. Building that from scratch means writing a lot of plumbing: a chat sidebar, streaming text, a way for the AI to read your app's current state, a way for it to call your functions, and a way to render the results as real interface elements instead of plain paragraphs.

CopilotKit — illustration
CopilotKit — windowslatest.com

CopilotKit is an open-source frontend stack for React and Angular that gives you all of that plumbing as ready-made building blocks. You drop in its components and hooks, tell it what parts of your app the AI is allowed to see and do, and you get an in-app copilot — a sidebar or inline assistant — plus generative UI, where the assistant can render actual widgets (a chart, a confirmation card, a progress list) rather than just text.

A useful analogy: think of a new hire who is brilliant but blind to your office. CopilotKit is the badge, the desk, and the phone system that let that hire see the room they're standing in and press the buttons that exist. The AI model is still the brain; CopilotKit is the wiring that connects the brain to your specific app — its current state, its functions, and its screen.

Why it matters

Almost every team that adds AI to a product hits the same wall. Wiring a model to a chat box is easy. Wiring it to your application — so it knows what the user is currently viewing and can take real actions safely — is a surprising amount of repetitive, fiddly work. CopilotKit exists to make that wiring a configuration step instead of a project.

The problems a ready-made copilot layer solves

  • State awareness. A generic chatbot has no idea what's on the user's screen. To answer "summarise the rows I filtered," the assistant must read your live app state. CopilotKit gives the AI structured, read-only access to exactly the state you choose to share.
  • Taking action. Reading is half the value; the other half is doing. CopilotKit lets you register frontend functions ("actions") the assistant is allowed to call — apply a filter, add an item, navigate — so the copilot can change the app, not just talk about it.
  • Generative UI. Plain text is the wrong answer for a lot of requests. CopilotKit lets an action or agent step render a real React/Angular component — a chart, a form, an approval card — so answers become interactive instead of a wall of prose. See generative UI patterns for the broader idea.
  • The boring-but-hard UX. Streaming responses, a polished sidebar, message history, loading states, and human-in-the-loop approvals are all things you'd otherwise hand-build. CopilotKit ships them.

Who cares? Mostly product teams adding AI to an existing SaaS app, internal-tool builders, and anyone shipping a "copilot" feature inside a real interface rather than a standalone chat site. If your AI needs to understand and manipulate a live UI — not just answer questions in a vacuum — a copilot layer saves weeks. If you only need a basic chat widget over some documents, this is more machinery than you need.

How it works

CopilotKit sits between your app and an agent backend. You wrap your app in a provider, then sprinkle in three kinds of declarations: what the AI can read (state), what it can do (actions), and where the assistant appears (UI components). At runtime, a user message flows to the agent along with that shared state; the agent decides whether to answer in text, call one of your actions, or render a component back into the page.

The three things you declare

In practice CopilotKit is mostly a set of hooks (in React) or equivalents (in Angular). You give the assistant readable context, you register callable actions, and you mount the chat UI. The library handles the message transport, streaming, and rendering.

shape of a CopilotKit integration (illustrative)typescript
// 1) Make app state readable by the copilot.
useCopilotReadable({
  description: "The rows currently visible in the table",
  value: visibleRows,
});

// 2) Let the copilot take an action in your app.
useCopilotAction({
  name: "applyFilter",
  description: "Filter the table by a column and value",
  parameters: [
    { name: "column", type: "string" },
    { name: "value", type: "string" },
  ],
  handler: ({ column, value }) => setFilter(column, value),
});

// 3) Mount the assistant UI somewhere in your tree.
// <CopilotSidebar /> renders the chat panel.

Where AG-UI fits underneath

The same team behind CopilotKit created AG-UI (the Agent-User Interaction Protocol), a standard event stream that describes what an agent is doing — emitting events like text chunk, tool call started, state updated, render this component. CopilotKit is the component layer a developer touches; AG-UI is the wire format flowing beneath it between the agent and the frontend. Because the protocol is open, a CopilotKit frontend can talk to many different agent backends as long as they speak AG-UI, instead of being locked to one vendor's SDK.

A concrete example

Picture a project-management dashboard with a board of tasks. You want a copilot in the sidebar that can both understand the board and change it. Here's the same turn told as a story rather than code.

  1. You expose the board to the assistant as readable state: the list of tasks, their statuses, and who's assigned. Now the AI can answer "what's overdue?" without you writing a special endpoint.
  2. You register an action called createTask with parameters like title, assignee, and due date, whose handler adds a card to the board.
  3. A user types "Add a task to ship the changelog, assign it to Maya, due Friday." The agent reads the board, calls createTask with those arguments, and your handler runs.
  4. Instead of replying "Done" in text, the action returns a generative UI card showing the new task with an Undo button — the user confirms at a glance and can reverse it in one click.

CopilotKit vs other frontend approaches

CopilotKit is one of several ways to build an AI frontend. It's most useful to see where it sits on the spectrum from "raw plumbing" to "opinionated copilot."

ApproachWhat you getBest when
CopilotKitIn-app copilot + actions + generative UI, state-aware, AG-UI underneathYou want an assistant that reads and acts on a live app
Composable chat kits (e.g. assistant-ui)Unstyled chat primitives you compose and ownYou mainly need a polished, custom chat surface
A provider's UI SDKChat + tool rendering tied to one model/runtimeYou're committed to a single vendor's stack
Hand-rolledFull control, zero abstractionsYou have unusual needs and time to maintain it

The dividing line is scope. A chat-component library is great when the hard part is the chat surface. CopilotKit aims higher: the hard part it targets is connecting the assistant to your application's state and actions, with generative UI as the payoff. If you only ever need a chat box, the extra concepts (readable state, actions, agent wiring) are weight you won't use.

Common pitfalls and good practices

  • Over-sharing state. Marking your entire app state readable floods the model with noise and can leak sensitive fields. Expose only the slices a copilot genuinely needs, with clear descriptions.
  • Unguarded actions. An action the model can call is a button anyone's prompt can press. Validate arguments in your handler, enforce permissions server-side, and never trust the model to respect limits you didn't enforce in code.
  • Skipping human-in-the-loop for risky steps. Deleting data or sending a message should pause for confirmation. Use an approval card (a generative-UI step) before destructive actions — see human-in-the-loop UX.
  • Generative UI everywhere. Not every answer needs a widget. Rendering custom components for trivial replies adds maintenance and can feel gimmicky. Reserve it for answers a chart, form, or card genuinely improves.
  • Ignoring latency and errors. Agent calls are slow and sometimes fail. Plan for streaming and perceived speed and graceful error states from the start, not as an afterthought.

Going deeper

Once the basics click — readable state, actions, mounted UI — the interesting questions are about how far the agent loop goes and how the frontend stays in sync with it.

Connecting real agent frameworks. Beyond simple one-shot actions, CopilotKit can front a full agent running in a framework on your backend. As that agent thinks, calls tools, and updates its working state, AG-UI streams those events to the frontend so the UI can reflect intermediate progress — a running tool, a partial plan, a state change — rather than freezing until the final answer. This is what makes a long-running agent feel alive in the interface instead of a spinner.

Shared state, both directions. The deeper pattern isn't just the model reading your state; it's bidirectional state. The agent and the UI share a view of the world, so a change the user makes in the app can update the agent's context, and a change the agent makes can update the UI. Keeping that in sync without race conditions or stale reads is the real engineering challenge in advanced copilots.

Framework-agnostic by design. Because the component layer (CopilotKit) and the protocol layer (AG-UI) are separate, you can in principle swap the backend agent without rewriting the frontend, or reuse the same agent across different frontends. That separation is the strategic reason to build on an open protocol rather than a single vendor's closed widget.

Where to go next: read generative UI patterns for the rendering side, what makes good AI UX for the design principles, and the broader AI UX patterns subcategory for the surrounding concerns — citations, error states, optimistic updates — that a production copilot has to get right alongside the core wiring.

FAQ

What is CopilotKit used for?

CopilotKit is used to add in-app AI copilots and generative UI to React and Angular applications. It gives the assistant read access to your app's state, lets it call frontend functions you register, and renders results as real interactive components (charts, forms, cards) instead of plain text.

Is CopilotKit free and open source?

Yes, CopilotKit is open source. Like many open-source projects it pairs the free libraries with optional paid/hosted offerings, but the core React and Angular components you build with are open. Check the official repository for current licensing details.

What is the difference between CopilotKit and AG-UI?

They're built by the same team and work together. CopilotKit is the frontend component layer that developers use (the sidebar, hooks, and generative-UI rendering). AG-UI is the open protocol — the event stream — that flows underneath between the agent backend and the frontend. CopilotKit is what you touch; AG-UI is the wire it runs on.

CopilotKit vs assistant-ui — which should I use?

Pick by scope. assistant-ui is a composable React kit focused on building a polished chat surface you fully own. CopilotKit aims higher: connecting an assistant to your live app state and actions, with generative UI as the goal. Choose assistant-ui when the chat UI is the hard part; choose CopilotKit when state-awareness and taking actions in the app are the hard part.

Does CopilotKit work without a specific AI model or backend?

CopilotKit is model- and framework-agnostic by design. It connects to an agent backend that speaks the AG-UI protocol, so you can use different models or agent frameworks behind it. The frontend stays the same while the backend can change.

Can the copilot actually change my app, or only chat?

It can change your app. You register "actions" — frontend functions with typed parameters — that the assistant is allowed to call, like applying a filter or creating a record. The model decides which action to call and with what data; your handler decides what actually happens, so authorization and validation stay in your code.

Further reading