# Migrating to react-langgraph v0.7
URL: /docs/migrations/react-langgraph-v0-7

Guide to upgrading to the simplified LangGraph integration API.

> For AI agents: a documentation index is available at [llms.txt](/llms.txt). Use `.md` for canonical markdown pages; `.mdx` is kept as a backwards-compatible alias on supported URL paths.

## Overview

This guide helps you migrate from the previous LangGraph integration pattern to the new simplified API introduced in `@assistant-ui/react-langgraph` v0.7. The new API consolidates thread management directly into `useLangGraphRuntime`, eliminating the need for separate runtime hooks and manual thread state management.

## Key Changes

### 1. Simplified Thread Management

The `useLangGraphRuntime` hook now directly handles thread lifecycle:

- No more `useRemoteThreadListRuntime` wrapper
- No more separate runtime hook functions
- Thread management is built into the core runtime

### 2. New `initialize` Parameter

The `stream` function now receives an `initialize` parameter that handles thread creation and loading automatically.

### 3. Direct Cloud Integration

Cloud persistence can now be configured directly in `useLangGraphRuntime` with the `cloud` parameter.

## Migration Steps

1. ### Update Your Runtime Implementation

   #### Before (Old Pattern)

   ```
   import {
     useCloudThreadListRuntime,
     useThreadListItemRuntime,
   } from "@assistant-ui/react";
   import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";

   const useMyLangGraphRuntime = () => {
     const threadListItemRuntime = useThreadListItemRuntime();

     const runtime = useLangGraphRuntime({
       stream: async function* (messages) {
         const { externalId } = await threadListItemRuntime.initialize();
         if (!externalId) throw new Error("Thread not found");

         return sendMessage({
           threadId: externalId,
           messages,
         });
       },
       onSwitchToThread: async (externalId) => {
         const state = await getThreadState(externalId);
         return {
           messages: state.values.messages,
         };
       },
     });

     return runtime;
   };

   // In your component:
   const runtime = useCloudThreadListRuntime({
     cloud,
     runtimeHook: useMyLangGraphRuntime,
     create: async () => {
       const { thread_id } = await createThread();
       return { externalId: thread_id };
     },
   });
   ```

   #### After (New Pattern)

   ```
   import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";

   // Directly in your component:
   const runtime = useLangGraphRuntime({
     cloud, // Optional: for cloud persistence
     stream: async function* (messages, { initialize }) {
       const { externalId } = await initialize();
       if (!externalId) throw new Error("Thread not found");

       return sendMessage({
         threadId: externalId,
         messages,
       });
     },
     create: async () => {
       const { thread_id } = await createThread();
       return { externalId: thread_id };
     },
     load: async (externalId) => {
       const state = await getThreadState(externalId);
       return {
         messages: state.values.messages,
       };
     },
   });
   ```

2. ### Update Import Statements

   Remove unused imports:

   ```
   - import {
   -   useCloudThreadListRuntime,
   -   useThreadListItemRuntime,
   - } from "@assistant-ui/react";
   + import { AssistantCloud } from "@assistant-ui/react";
   ```

3. ### Simplify Component Structure

   You no longer need a separate runtime hook function. Everything can be defined directly in your component or provider:

   ```
   export function MyRuntimeProvider({ children }) {
     const cloud = useMemo(
       () => new AssistantCloud({
         baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL,
         anonymous: true,
       }),
       []
     );

     const runtime = useLangGraphRuntime({
       cloud,
       // All configuration inline
       stream: async function* (messages, { initialize }) {
         // Your stream implementation
       },
       create: async () => {
         // Your create implementation
       },
       load: async (externalId) => {
         // Your load implementation
       },
     });

     return (
       <AssistantRuntimeProvider runtime={runtime}>
         {children}
       </AssistantRuntimeProvider>
     );
   }
   ```

4. ### Update Method Names

   Rename methods to match the new API:

   - `onSwitchToThread` → `load`
   - `onSwitchToNewThread` → handled automatically via `create`
   - Thread ID management is now automatic

## API Reference Changes

### Old API

```
type OldLangGraphRuntimeOptions = {
  threadId?: string;
  stream: (messages: Message[]) => AsyncGenerator;
  onSwitchToNewThread?: () => Promise<void>;
  onSwitchToThread?: (threadId: string) => Promise<ThreadState>;
};
```

### New API

```
type NewLangGraphRuntimeOptions = {
  cloud?: AssistantCloud;
  stream: (
    messages: Message[],
    config: {
      abortSignal: AbortSignal;
      initialize: () => Promise<{
        remoteId: string;
        externalId: string | undefined;
      }>;
      command?: { resume: string };
      runConfig?: unknown;
      checkpointId?: string;
    }
  ) => AsyncGenerator;
  create?: () => Promise<{ externalId: string }>;
  load?: (threadId: string) => Promise<ThreadState>;
  delete?: (threadId: string) => Promise<void>;
};
```

## Benefits of the New API

1. **Simpler Setup**: No need for multiple runtime hooks and wrappers
2. **Cleaner Code**: All configuration in one place
3. **Better Type Safety**: More explicit types for thread management
4. **Automatic Thread Handling**: The runtime manages thread lifecycle internally
5. **Optional Cloud Integration**: Add cloud persistence with a single parameter

## Common Migration Issues

> [!warning]
>
> **Breaking Change**: The `threadId` and `onSwitchToNewThread` parameters are no longer supported. Use the new `create` and `load` methods instead.

### Issue: `threadListItemRuntime` is not defined

**Solution**: Remove references to `useThreadListItemRuntime()`. Use the `initialize` parameter in the stream function instead.

### Issue: Thread switching doesn't work

**Solution**: Ensure you've implemented both `create` and `load` functions. The runtime needs both to manage thread lifecycle.

### Issue: Cloud persistence not working

**Solution**: Pass the `AssistantCloud` instance directly to `useLangGraphRuntime` via the `cloud` parameter.

## Example: Complete Migration

Here's a complete before and after example for a typical LangGraph integration:

### Before

```
import {
  AssistantCloud,
  AssistantRuntimeProvider,
  useCloudThreadListRuntime,
  useThreadListItemRuntime,
} from "@assistant-ui/react";
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";

const useMyRuntime = () => {
  const threadListItemRuntime = useThreadListItemRuntime();

  return useLangGraphRuntime({
    stream: async function* (messages) {
      const { externalId } = await threadListItemRuntime.initialize();
      // ... implementation
    },
    onSwitchToThread: async (externalId) => {
      // ... implementation
    },
  });
};

export function Provider({ children }) {
  const cloud = new AssistantCloud({ /* config */ });

  const runtime = useCloudThreadListRuntime({
    cloud,
    runtimeHook: useMyRuntime,
    create: async () => { /* ... */ },
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      {children}
    </AssistantRuntimeProvider>
  );
}
```

### After

```
import {
  AssistantCloud,
  AssistantRuntimeProvider,
} from "@assistant-ui/react";
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";

export function Provider({ children }) {
  const cloud = new AssistantCloud({ /* config */ });

  const runtime = useLangGraphRuntime({
    cloud,
    stream: async function* (messages, { initialize }) {
      const { externalId } = await initialize();
      // ... implementation
    },
    create: async () => { /* ... */ },
    load: async (externalId) => {
      // ... implementation (formerly onSwitchToThread)
    },
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      {children}
    </AssistantRuntimeProvider>
  );
}
```

## Need Help?

If you encounter issues during migration:

1. Check the updated [LangGraph documentation](/docs/runtimes/langgraph/overview)
2. Review the [example implementation](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-langgraph)
3. Report issues on [GitHub](https://github.com/assistant-ui/assistant-ui/issues)