---
title: Shared State
description: Create a two-way connection between your UI and agent state.
icon: "lucide/Repeat"
---
## What is shared state?

Agentic Copilots maintain a shared state that seamlessly connects your UI with the agent's execution. This shared state system allows you to:

- Display the agent's current progress and intermediate results
- Update the agent's state through UI interactions
- React to state changes in real-time across your application

<ImageZoom
  src="https://cdn.copilotkit.ai/docs/copilotkit/images/coagents/SharedStateCoAgents.gif"
  alt="Shared State Demo"
  width={1000}
  height={1000}
  className="rounded-lg shadow-lg border mt-0"
/>

## When should I use this?

Use shared state when you want to facilitate collaboration between your agent and the user. Updates flow both ways — the agent's outputs are automatically reflected in the UI, and any inputs the user updates in the UI are automatically reflected in the agent's execution.

<OpsPlatformCTA
  variant="inline"
  title="Building stateful agents?"
  body="Persistent threads ship with the Enterprise Intelligence Platform on the free Developer tier."
  surface="docs_shared_state"
/>

## Reading agent state

<FrameworkSetup concept="shared-state-setup" />

Subscribe a component to the agent's state with `useAgent`. Any time the agent
mutates its state — for example via a tool call — the hook fires and your UI
re-renders with the new values.

<Snippet region="use-agent-read" cell="shared-state-read-write" title="frontend/src/app/page.tsx — useAgent subscription" />

The returned `agent.state` is just a plain object. Read it like any other
piece of React state and render the parts you care about — agent-written
notes, structured outputs, progress indicators, anything the agent has put
there.

## Writing agent state

The same `agent` object exposes a `setState` setter. Calling it from a UI
event handler pushes the new value into shared state, and the agent reads it
back on its next turn — so the UI's writes visibly steer the model.

<Snippet region="use-agent-write" cell="shared-state-read-write" title="frontend/src/app/page.tsx — agent.setState" />

This is what makes the channel two-way: the UI doesn't just observe the
agent, it can hand the agent fresh inputs (preferences, selections, partial
work) without going through the chat thread.

## Rendering shared state in the UI

Because `agent.state` is plain React data, the UI layer is whatever you'd
normally build. The demo on this page wires the agent's outputs into a
small card component and feeds user edits back through `setState`.

<Snippet region="notes-card-render" cell="shared-state-read-write" title="frontend/src/app/page.tsx — NotesCard" />

## Streaming partial state updates

By default, agent state only updates *between* node transitions, so a
long-running tool call appears as one big burst at the end. State streaming
forwards a specific tool argument straight into a state key *as it's being
generated*, so the UI can watch the answer assemble token-by-token.

<Snippet region="state-streaming-middleware" cell="shared-state-streaming" title="backend — streaming state update" />

See **[State streaming](/shared-state/streaming)** for the full walkthrough,
including the corresponding `useAgent` subscription on the frontend.

## Read-only context

When the value is **UI-owned** and the agent should read it but never write
it back — current user, selected record, scroll position — reach for
`useAgentContext` instead of full shared state. It publishes values as a
one-way UI → agent channel that auto-unregisters on unmount.

See **[Agent read-only context](/shared-state/agent-readonly)** for the
full pattern.

<IntegrationGrid path="shared-state" exclude={["agno", "agent-spec", "spring-ai", "langroid"]} />
