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
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.
Public v1 name for TransportAdapter plus optional high-level
Reactive tool handle for framework bindings (stream.toolCalls,
Shared surface across every media handle returned by
Player controls + live state returned by useAudioPlayer.
Shared surface across every media handle returned by
Client-side implementation returned by headlessTool.implement(...).
Represents a headless tool interrupt payload emitted by LangChain's
Shared surface across every media handle returned by
Shared surface across every media handle returned by
Metadata tracked per message id. Surfaced to applications via
Options for StreamController.stop / framework stop().
Lightweight discovery record for a subagent running inside the thread.
Lightweight discovery record for a subgraph running inside the thread.
Queued submission entry mirrored from the server-side run queue.
Options for useAudioPlayer.
Reactive handle on the server-side submission queue.
Options for useVideoPlayer.
Shared surface across every media handle returned by
Controls + live state returned by useVideoPlayer. Mirrors
Erased stream handle useful as a parameter type for helpers and
Default tool call type when no specific tool definitions are provided.
Unwrap the state shape from a compiled graph, a create-agent brand,
Infer the subagent → state map from a DeepAgent brand. Non-brands
Infer the discriminated union of AssembledToolCall handles
Infer the successful return type of a LangChain tool.
Kinds of failure that can terminate a media handle prematurely.
Block types this assembler knows how to reassemble into media handles.
Read-only map exposed via MessageMetadataTracker.store.
Lifecycle state of an audio or video player returned by
What a selector hook can be targeted at. Callers can pass any of:
Props for StreamProvider when wiring a custom
Props for StreamProvider when talking to the default
Read-only snapshot of the queue. The queue store hands this out
Infer the streaming AssembledToolCall handle for a single
Infer a union of tool call types from an array of tools.
The lifecycle state of a tool call.
High-level outcome of a single tool call.
Convenience alias for the fully-resolved stream handle type.
Return shape of useSuspenseStream. Identical to the
Widen an update type so its messages field also accepts