State Rendering
Render your agent's state with custom UI components in real-time.
Open your coding agent in your project's folder, or in an empty folder for a new app.This runs in a coding agent on your computer.
What is this?#
State rendering lets you build UI that reflects your agent's state in real-time. As your agent progresses through nodes and emits state updates, your frontend renders those changes, showing progress, drafts, or intermediate results.
Free course: See this pattern built end-to-end in Build Interactive Agents with Generative UI — a free DeepLearning.AI short course taught by CopilotKit's CEO covering the full Generative UI spectrum (Controlled, Declarative, and Open-Ended).
When should I use this?#
Use state rendering when you want to:
- Show real-time progress (e.g. "Researching... 2/5 complete")
- Display drafts that update as the agent works
- Build dashboards that reflect agent state
- Render structured output outside of the chat
How it works in code#
On the frontend, subscribe to the agent's state. Each time the backend forwards a fresh value, your component re-renders with the latest partial output.
// Subscribe to BOTH state changes and run-status changes. The former // drives the per-token document rerender; the latter toggles the // "LIVE" badge when the agent starts / stops. const { agent } = useAgent({ agentId: "shared-state-streaming", updates: [UseAgentUpdate.OnStateChanged, UseAgentUpdate.OnRunStatusChanged], });On the backend, a state-streaming mapping forwards a specific tool argument
straight into a state key as it's being generated. Some frameworks provide
that as middleware; direct SDK adapters can emit STATE_SNAPSHOT events from
their streaming loop. Either way, the UI can watch the answer assemble
token-by-token rather than appearing in one burst between checkpoints.
Install the CopilotKit LangGraph SDK
npm install @copilotkit/sdk-jsMap generated content into shared state while it streams
Extend your graph state with CopilotKitStateAnnotation, then call
copilotkitCustomizeConfig with an emitIntermediateState mapping. This
forwards the write_document.document tool argument into state.document
while the model is still generating it.
const streamingConfig = copilotkitCustomizeConfig(config, {
emitIntermediateState: [
{
stateKey: "document",
tool: "write_document",
toolArgument: "document",
},
],
});
const response = await modelWithTools.invoke(
[systemMessage, ...state.messages],
streamingConfig,
); const streamingConfig = copilotkitCustomizeConfig(config, { emitIntermediateState: [ { stateKey: "document", tool: "write_document", toolArgument: "document", }, ], }); const response = await modelWithTools.invoke( [systemMessage, ...state.messages], streamingConfig, );