How to build your own chat UI from scratch on top of CopilotKit's primitives — no CopilotChat component, no slots. You own the message list, the input, and the send button; CopilotKit owns the agent connection and tool routing.
- Custom message list: iterate over
agent.messagesand render your own bubbles for user and assistant roles - Custom input: a plain textarea + button drive
agent.addMessageandcopilotkit.runAgent - Generative UI still works:
useComponentregisters ashow_cardcomponent that the agent can render inside your custom layout
Type any prompt. For example:
- "Show a card about cats"
- "Show me a card titled 'CopilotKit' with a short description"
- "Say hi"
Asking for a card triggers the show_card component, which renders as a titled card inside your custom message list.
CopilotKitwires the page withruntimeUrl="/api/copilotkit"andagent="headless-simple", backed by the defaultgraphinsrc/agents/main.pyuseAgent({ agentId: "headless-simple" })exposesagent.messages,agent.isRunning, andagent.addMessage;useCopilotKitexposescopilotkit.runAgentfor triggering a runuseComponentregisters theshow_cardcomponent (title + body, zod-typed) anduseRenderToolCallreturns a renderer that turns tool calls into React- Calling
copilotkit.runAgent({ agent })(notagent.runAgent()directly) is required so that frontend-registered components are forwarded to the agent - Reach for headless when you need full control over the chat shell; use
CopilotChat+ slots for anything less drastic