# 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<T>(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<T>(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<T>(key)`     | New — reads any custom state key reactively.                                          |
