# Comparison with `react-langgraph` URL: /docs/runtimes/langchain/comparison How `@assistant-ui/react-langchain` differs from `@assistant-ui/react-langgraph`. Both packages connect assistant-ui to LangGraph backends. They are **independent adapters for different upstream libraries** — one is not a successor to the other. | Aspect | `@assistant-ui/react-langgraph` | `@assistant-ui/react-langchain` | | ------------------------------ | ------------------------------------ | ------------------------------------- | | Wraps | `@langchain/langgraph-sdk` (raw SDK) | `@langchain/react` (`useStream` hook) | | Age | Sept 2024 onward | April 2026 onward | | Version | `0.13.x` | `0.0.x` | | Lines of source | \~7,500 | \~600 | | Built on | `useExternalStoreRuntime` | `useExternalStoreRuntime` | | `create-assistant-ui` template | `-t langgraph` ships this package | No template yet | Feature coverage \[#feature-coverage] | Feature | `react-langgraph` | `react-langchain` | | --------------------------------------- | ---------------------------------- | ------------------------------ | | Stream messages | ✅ `useLangGraphRuntime` | ✅ `useStreamRuntime` | | Interrupt state | ✅ `useLangGraphInterruptState` | ✅ `useLangChainInterruptState` | | Send raw state update / resume command | ✅ `useLangGraphSendCommand` | ✅ `useLangChainSubmit` | | Read arbitrary custom state key | ❌ | ✅ `useLangChainState(key)` | | Per-message metadata (`messages-tuple`) | ✅ `useLangGraphMessageMetadata` | ❌ not exposed | | Generative UI messages (LangSmith) | ✅ `useLangGraphUIMessages` | ❌ not exposed | | Subgraph / namespaced stream events | ✅ via `eventHandlers` | ❌ not exposed | | End-to-end cancellation primitive | ✅ `unstable_createLangGraphStream` | ❌ not exposed | | Message accumulator utility | ✅ `LangGraphMessageAccumulator` | ❌ not exposed | | Cloud thread persistence | ✅ `cloud` option | ✅ `cloud` option | `react-langchain` is the newer, thinner wrapper — it delegates to the upstream `useStream` hook rather than re-implementing the stream plumbing. That is why its footprint is smaller and its surface area is narrower today. Features that exist in `react-langgraph` but not `react-langchain` are absent because they have not yet been ported, not because they are deprecated. Choosing between them \[#choosing-between-them] Use `@assistant-ui/react-langgraph` when: * You are scaffolding via `npx create-assistant-ui -t langgraph`. * You want the broader feature set today (subgraph events, UI messages, message metadata, cancellation). * You prefer integrating with `@langchain/langgraph-sdk` directly. Use `@assistant-ui/react-langchain` when: * Your app already depends on `@langchain/react` and uses `useStream` elsewhere. * You want to read custom state keys (`todos`, `files`, plans, ...) with `useLangChainState(key)` without reconstructing them from tool-call streams. * You prefer a thin wrapper that stays pinned to upstream behavior. Hook name mapping \[#hook-name-mapping] If you are moving code between the two adapters, most hooks have a counterpart — but note the feature gaps above. | `react-langgraph` | `react-langchain` | Notes | | ----------------------------- | ------------------------------- | ------------------------------------------------------------------------------------- | | `useLangGraphRuntime` | `useStreamRuntime` | Options extend upstream `UseStreamOptions`; no `stream` / `create` / `load` to write. | | `useLangGraphInterruptState` | `useLangChainInterruptState` | Same return shape: `{ value?: unknown } \| undefined`. | | `useLangGraphSendCommand` | `useLangChainSubmit` | `submit(values, { command })` replaces the dedicated hook. | | `useLangGraphSend` | *(use `runtime.thread.append`)* | No direct equivalent; send turns through the runtime. | | `useLangGraphMessageMetadata` | *(not available)* | Open an issue if you rely on this. | | `useLangGraphUIMessages` | *(not available)* | Open an issue if you rely on this. | | *(none)* | `useLangChainState(key)` | New — reads any custom state key reactively. |