React SDK for building AI-powered applications with Deep Agents, LangChain and LangGraph.
@langchain/react v1 ships a v2-native useStream hook together with a small family of companion selector hooks. The root hook gives you always-on access to thread state, messages, tool calls, and interrupts; the selector hooks open ref-counted subscriptions for the things that aren't needed on every view (per-subagent messages, media streams, submission queue, message metadata, raw channels, …).
reconnectOnMount / joinStream dance.values, messages, toolCalls, and interrupts are live at the root with zero per-subscription cost.useStream<typeof agent>() unwraps state, tool calls, and subagent state maps from an agent brand.useSuspenseStream hands the initial hydration phase to <Suspense> and non-streaming errors to Error Boundaries.npm install @langchain/react @langchain/core
Peer dependencies: react (^18 || ^19), @langchain/core (^1.1.27).
import { useStream } from "@langchain/react";
function Chat() {
const { messages, submit, isLoading } = useStream({
assistantId: "agent",
apiUrl: "http://localhost:2024",
});
return (
<div>
{messages.map((msg, i) => (
<div key={msg.id ?? i}>{String(msg.content)}</div>
))}
<button
disabled={isLoading}
onClick={() =>
void submit({
messages: [{ type: "human", content: "Hello!" }],
})
}
>
Send
</button>
</div>
);
}
@langchain/react v1 splits the surface into two layers:
useStream). Owns the thread lifecycle, the transport, and a handful of always-on projections (values, messages, toolCalls, interrupts, error, isLoading, discovery maps). Mount it once per thread.import {
useStream,
useMessages,
useToolCalls,
useSubmissionQueue,
} from "@langchain/react";
function Chat() {
const stream = useStream({ assistantId: "agent", apiUrl: "/api" });
// Root: free reads, no new subscription.
const messages = useMessages(stream); // same as stream.messages
// Scoped: opens a namespaced subscription on mount.
const queue = useSubmissionQueue(stream);
}
Detailed guides live in ./docs. Start with the two files most apps need first:
useStream — options, return shape, submit(), stop(), respond(), hydrationPromise.useValues, useMessages, useToolCalls, useMessageMetadata, useChannel, useExtension, and friends.Feature-specific guides:
HttpAgentServerAdapter, custom AgentServerAdapter.AgentServerAdapter against your own backend, with a worked walkthrough of examples/ui-react-transport.respond(), tools + onTool.useMessageMetadata + submit({ forkFrom }).multitaskStrategy: "enqueue" + useSubmissionQueue.useAudio / useImages / useVideo / useFiles, useMediaURL, players.useSuspenseStream — Suspense + Error Boundary integration.StreamProvider / useStreamContext — share one stream across a subtree.The useStream import name is unchanged, but the return shape, option bag, and protocol semantics all shifted. Most chat apps migrate in well under an hour — the full migration guide with line-by-line diffs lives in ./docs/v1-migration.md.
Legacy type aliases (UseStream, UseSuspenseStream, UseStreamOptions, UseStreamTransport, QueueEntry, GetToolCallsType, SubagentStream, …) and the legacy FetchStreamTransport class are no longer re-exported from @langchain/react. Apps still on the legacy surface can import directly from @langchain/langgraph-sdk/ui during their migration.
For complete end-to-end examples with full agentic UIs, visit the LangChain UI Playground.
MIT
Resume a headless-tool batch on the v1 commands transport.
Strip headless-tool interrupts from a user-facing interrupt list.
Execute and resume all newly seen headless-tool interrupts from a values
Parses a headless-tool interrupt value from the graph. Accepts both
Provides a shared useStream instance to all descendants via
Subscribe to a scoped audio-media stream. Returns an array of
Progressive audio playback for AudioMedia handles with a
Raw-events escape hatch. Subscribes to one or more channels at a
Side-effect counterpart to useChannel. Instead of returning a
Subscribe to a custom:<name> stream extension — the most-recent
Subscribe to a scoped file-media stream. See useAudio for
Subscribe to a scoped image-media stream. See useAudio for
Resolve the lazy MediaBase.objectURL promise into a string
Read metadata recorded for a specific message id — today exposes
Subscribe to a scoped messages stream. Pass stream and
React-side primitive that composes ChannelRegistry.acquire
React binding for the v2-native stream runtime.
Accesses the shared stream instance from the nearest
Subscribe to a scoped tools (tool-call) stream. Same target and
Subscribe to a scoped values stream — most-recent state payload
Subscribe to a scoped video-media stream. See useAudio for
Bind a VideoMedia handle to a caller-owned <video> element.