> ## Documentation Index
> Fetch the complete documentation index at: https://docs.langchain.com/llms.txt
> Use this file to discover all available pages before exploring further.

# LangChain v1 migration guide

This migration guide outlines the major changes in LangChain v1. To learn more about the new features of v1, see the [introductory post](/oss/javascript/releases/langchain-v1).

To upgrade,

<CodeGroup>
  ```bash npm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  npm install langchain@latest @langchain/core@latest
  ```

  ```bash pnpm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  pnpm install langchain@latest @langchain/core@latest
  ```

  ```bash yarn theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  yarn add langchain@latest @langchain/core@latest
  ```

  ```bash bun theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  bun add langchain@latest @langchain/core@latest
  ```
</CodeGroup>

## `createAgent`

In v1, the react agent prebuilt is now in the langchain package. The table below outlines what functionality has changed:

| Section                                            | What changed                                                                             |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| [Import path](#import-path)                        | Package moved from `@langchain/langgraph/prebuilts` to `langchain`                       |
| [Prompts](#prompts)                                | Parameter renamed to `systemPrompt`, dynamic prompts use middleware                      |
| [Pre-model hook](#pre-model-hook)                  | Replaced by middleware with `beforeModel` method                                         |
| [Post-model hook](#post-model-hook)                | Replaced by middleware with `afterModel` method                                          |
| [Custom state](#custom-state)                      | Defined in middleware, zod objects only                                                  |
| [Model](#model)                                    | Dynamic selection via middleware, pre-bound models not supported                         |
| [Tools](#tools)                                    | Tool error handling moved to middleware with `wrapToolCall`                              |
| [Structured output](#structured-output)            | prompted output removed, use `toolStrategy`/`providerStrategy`                           |
| [Streaming node name](#streaming-node-name-rename) | Node name changed from `"agent"` to `"model"`                                            |
| [Runtime context](#runtime-context)                | `context` property instead of `config.configurable`                                      |
| [Namespace](#simplified-package)                   | Streamlined to focus on agent building blocks, legacy code moved to `@langchain/classic` |

### Import path

The import path for the react agent prebuilt has changed from `@langchain/langgraph/prebuilts` to `langchain`. The name of the function has changed from `createReactAgent` to `createAgent`:

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { createReactAgent } from "@langchain/langgraph/prebuilts"; // [!code --]
import { createAgent } from "langchain"; // [!code ++]
```

### Prompts

#### Static prompt rename

The `prompt` parameter has been renamed to `systemPrompt`:

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createAgent } from "langchain";

  agent = createAgent({
    model,
    tools,
    systemPrompt: "You are a helpful assistant.", // [!code highlight]
  });
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createReactAgent } from "@langchain/langgraph/prebuilts";

  const agent = createReactAgent({
    model,
    tools,
    prompt: "You are a helpful assistant.", // [!code highlight]
  });
  ```
</CodeGroup>

#### `SystemMessage`

If using `SystemMessage` objects in the system prompt, the string content is now used directly:

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { SystemMessage, createAgent } from "langchain";

  const agent = createAgent({
    model,
    tools,
    systemPrompt: "You are a helpful assistant.", // [!code highlight]
  });
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createReactAgent } from "@langchain/langgraph/prebuilts";

  const agent = createReactAgent({
    model,
    tools,
    prompt: new SystemMessage(content: "You are a helpful assistant."), // [!code highlight]
  });
  ```
</CodeGroup>

#### Dynamic prompts

Dynamic prompts are a core context engineering pattern—they adapt what you tell the model based on the current conversation state. To do this, use `dynamicSystemPromptMiddleware`:

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createAgent, dynamicSystemPromptMiddleware } from "langchain";
  import * as z from "zod";

  const contextSchema = z.object({
    userRole: z.enum(["expert", "beginner"]).default("beginner"),
  });

  const userRolePrompt = dynamicSystemPromptMiddleware<z.infer<typeof contextSchema>>( // [!code highlight]
      (_state, runtime) => {
          const userRole = runtime.context.userRole;
          const basePrompt = "You are a helpful assistant.";

          if (userRole === "expert") {
              return `${basePrompt} Provide detailed technical responses.`;
          } else if (userRole === "beginner") {
              return `${basePrompt} Explain concepts simply and avoid jargon.`;
          }
          return basePrompt; // [!code highlight]
      }
  );

  const agent = createAgent({
    model,
    tools,
    middleware: [userRolePrompt],
    contextSchema,
  });

  await agent.invoke(
    {
      messages: [new HumanMessage("Explain async programming")],
    },
    {
      context: {
        userRole: "expert",
      },
    }
  );
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createReactAgent } from "@langchain/langgraph/prebuilts";

  const contextSchema = z.object({
    userRole: z.enum(["expert", "beginner"]),
  });

  const agent = createReactAgent({
    model,
    tools,
    prompt: (state) => {
      const userRole = state.context.userRole;
      const basePrompt = "You are a helpful assistant.";

      if (userRole === "expert") {
        return `${basePrompt} Provide detailed technical responses.`;
      } else if (userRole === "beginner") {
        return `${basePrompt} Explain concepts simply and avoid jargon.`;
      }
      return basePrompt;
    },
    contextSchema,
  });

  // Use with context via config.configurable
  await agent.invoke(
    {
      messages: [new HumanMessage("Explain async programming")],
    },
    {
      config: {
        configurable: { userRole: "expert" },
      },
    }
  );
  ```
</CodeGroup>

### Pre-model hook

Pre-model hooks are now implemented as middleware with the `beforeModel` method. This pattern is more extensible--you can define multiple middlewares to run before the model is called and reuse them across agents.

Common use cases include:

* Summarizing conversation history
* Trimming messages
* Input guardrails, like PII redaction

v1 includes built-in summarization middleware:

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createAgent, summarizationMiddleware } from "langchain";

  const agent = createAgent({
    model: "claude-sonnet-4-6",
    tools,
    middleware: [
      summarizationMiddleware({
        model: "claude-sonnet-4-6",
        trigger: { tokens: 1000 },
      }),
    ],
  });
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createReactAgent } from "@langchain/langgraph/prebuilts";

  function customSummarization(state) {
    // Custom logic for message summarization
  }

  const agent = createReactAgent({
    model: "claude-sonnet-4-6",
    tools,
    preModelHook: customSummarization,
  });
  ```
</CodeGroup>

### Post-model hook

Post-model hooks are now implemented as middleware with the `afterModel` method. This lets you compose multiple handlers after the model responds.

Common use cases include:

* Human-in-the-loop approval
* Output guardrails

v1 includes a built-in human-in-the-loop middleware:

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createAgent, humanInTheLoopMiddleware } from "langchain";

  const agent = createAgent({
    model: "claude-sonnet-4-6",
    tools: [readEmail, sendEmail],
    middleware: [
      humanInTheLoopMiddleware({
        interruptOn: {
          sendEmail: { allowedDecisions: ["approve", "edit", "reject"] },
        },
      }),
    ],
  });
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createReactAgent } from "@langchain/langgraph/prebuilts";

  function customHumanInTheLoopHook(state) {
    // Custom approval logic
  }

  const agent = createReactAgent({
    model: "claude-sonnet-4-6",
    tools: [readEmail, sendEmail],
    postModelHook: customHumanInTheLoopHook,
  });
  ```
</CodeGroup>

### Custom state

Custom state is now defined in middleware using the `stateSchema` property. Use Zod to declare additional state fields that are carried through the agent run.

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import * as z from "zod";
  import { createAgent, createMiddleware, tool } from "langchain";

  const UserState = z.object({
    userName: z.string(),
  });

  const userState = createMiddleware({
    name: "UserState",
    stateSchema: UserState,
    beforeModel: (state) => {
      // Access custom state properties
      const name = state.userName;
      // Optionally modify messages/system prompt based on state
      return;
    },
  });

  const greet = tool(
    async () => {
      return "Hello!";
    },
    {
      name: "greet",
      description: "Greet the user",
      schema: z.object({}),
    }
  );

  const agent = createAgent({
    model: "claude-sonnet-4-6",
    tools: [greet],
    middleware: [userState],
  });

  await agent.invoke({
    messages: [{ role: "user", content: "Hi" }],
    userName: "Ada",
  });
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { getCurrentTaskInput } from "@langchain/langgraph";
  import { createReactAgent } from "@langchain/langgraph/prebuilts";
  import * as z from "zod";

  const UserState = z.object({
    userName: z.string(),
  });

  const greet = tool(
    async () => {
      const state = await getCurrentTaskInput();
      const userName = state.userName;
      return `Hello ${userName}!`;
    },
  );

  // Custom state was provided via agent-level state schema or accessed ad hoc in hooks
  const agent = createReactAgent({
    model: "claude-sonnet-4-6",
    tools: [greet],
    stateSchema: UserState,
  });
  ```
</CodeGroup>

### Model

Dynamic model selection now happens via middleware. Use `wrapModelCall` to swap models (and tools) based on state or runtime context. In `createReactAgent`, this was done via a function passed to the `model` parameter.

This functionality has been ported to the middleware interface in v1.

#### Dynamic model selection

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createAgent, createMiddleware } from "langchain";

  const dynamicModel = createMiddleware({
    name: "DynamicModel",
    wrapModelCall: (request, handler) => {
      const messageCount = request.state.messages.length;
      const model = messageCount > 10 ? "openai:gpt-5.4" : "openai:gpt-5-nano";
      return handler({ ...request, model });
    },
  });

  const agent = createAgent({
    model: "gpt-5-nano",
    tools,
    middleware: [dynamicModel],
  });
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createReactAgent } from "@langchain/langgraph/prebuilts";

  function selectModel(state) {
    return state.messages.length > 10 ? "openai:gpt-5.4" : "openai:gpt-5-nano";
  }

  const agent = createReactAgent({
    model: selectModel,
    tools,
  });
  ```
</CodeGroup>

#### Pre-bound models

To better support structured output, `createAgent` should receive a plain model (string or instance) and a separate `tools` list. Avoid passing models pre-bound with tools when using structured output.

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
// No longer supported
// const modelWithTools = new ChatOpenAI({ model: "gpt-5.4-mini" }).bindTools([someTool]);
// const agent = createAgent({ model: modelWithTools, tools: [] });

// Use instead
const agent = createAgent({ model: "gpt-5.4-mini", tools: [someTool] });
```

### Tools

The `tools` argument to `createAgent` accepts:

* Functions created with `tool`
* LangChain tool instances
* Objects that represent built-in provider tools

#### Handling tool errors

You can now configure the handling of tool errors with middleware implementing the `wrapToolCall` method.

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createAgent, createMiddleware, ToolMessage } from "langchain";

  const handleToolErrors = createMiddleware({
    name: "HandleToolErrors",
    wrapToolCall: async (request, handler) => {
      try {
        return await handler(request);
      } catch (error) {
        // Only handle errors that occur during tool execution due to invalid inputs
        // that pass schema validation but fail at runtime (e.g., invalid SQL syntax).
        // Do NOT handle:
        // - Network failures (use tool retry middleware instead)
        // - Incorrect tool implementation errors (should bubble up)
        // - Schema mismatch errors (already auto-handled by the framework)
        //
        // Return a custom error message to the model
        return new ToolMessage({
          content: `Tool error: Please check your input and try again. (${error})`,
          tool_call_id: request.toolCall.id!,
        });
      }
    },
  });

  const agent = createAgent({
    model: "claude-sonnet-4-6",
    tools: [checkWeather, searchWeb],
    middleware: [handleToolErrors],
  });
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createReactAgent, ToolNode } from "@langchain/langgraph/prebuilts";

  const agent = createReactAgent({
    model: "claude-sonnet-4-6",
    tools: new ToolNode(
      [checkWeather, searchWeb],
      { handleToolErrors: true } // [!code highlight]
    ),
  });
  ```
</CodeGroup>

### Structured output

#### Node changes

Structured output used to be generated in a separate node from the main agent. This is no longer the case. Structured output is generated in the main loop (no extra LLM call), reducing cost and latency.

#### Tool and provider strategies

In v1, there are two strategies:

* `toolStrategy` uses artificial tool calling to generate structured output
* `providerStrategy` uses provider-native structured output generation

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createAgent, toolStrategy } from "langchain";
  import * as z from "zod";

  const OutputSchema = z.object({
    summary: z.string(),
    sentiment: z.string(),
  });

  const agent = createAgent({
    model: "gpt-5.4-mini",
    tools,
    // explicitly using tool strategy
    responseFormat: toolStrategy(OutputSchema), // [!code highlight]
  });
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createReactAgent } from "@langchain/langgraph/prebuilts";
  import * as z from "zod";

  const OutputSchema = z.object({
    summary: z.string(),
    sentiment: z.string(),
  });

  const agent = createReactAgent({
    model: "gpt-5.4-mini",
    tools,
    // Structured output was driven primarily via tool-calling with fewer options
    responseFormat: OutputSchema,
  });
  ```
</CodeGroup>

#### Prompted output removed

Prompted output via custom instructions in `responseFormat` is removed in favor of the above strategies.

### Streaming node name rename

When streaming events from agents, the node name was changed from `"agent"` to `"model"` to better reflect the node's purpose.

### Runtime context

When invoking an agent, pass static, read-only configuration via the `context` config argument. This replaces patterns that used `config.configurable`.

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createAgent, HumanMessage } from "langchain";
  import * as z from "zod";

  const agent = createAgent({
    model: "gpt-5.4",
    tools,
    contextSchema: z.object({ userId: z.string(), sessionId: z.string() }),
  });

  const result = await agent.invoke(
    { messages: [new HumanMessage("Hello")] },
    { context: { userId: "123", sessionId: "abc" } }, // [!code highlight]
  );
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { createReactAgent, HumanMessage } from "@langchain/langgraph/prebuilts";

  const agent = createReactAgent({ model, tools });

  // Pass context via config.configurable
  const result = await agent.invoke(
    { messages: [new HumanMessage("Hello")] },
    {
      config: { // [!code highlight]
        configurable: { userId: "123", sessionId: "abc" }, // [!code highlight]
      }, // [!code highlight]
    }
  );
  ```
</CodeGroup>

<Note>
  The old `config.configurable` pattern still works for backward compatibility, but using the new `context` parameter is recommended for new applications or applications migrating to v1.
</Note>

***

## Standard content

In v1, messages gain provider-agnostic standard content blocks. Access them via `message.contentBlocks` for a consistent, typed view across providers. The existing `message.content` field remains unchanged for strings or provider-native structures.

### What changed

* New `contentBlocks` property on messages for normalized content.
* New TypeScript types under `ContentBlock` for strong typing.
* Optional serialization of standard blocks into `content` via `LC_OUTPUT_VERSION=v1` or `outputVersion: "v1"`.

### Read standardized content

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { initChatModel } from "langchain";

  const model = await initChatModel("gpt-5-nano");
  const response = await model.invoke("Explain AI");

  for (const block of response.contentBlocks) {
    if (block.type === "reasoning") {
      console.log(block.reasoning);
    } else if (block.type === "text") {
      console.log(block.text);
    }
  }
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  // Provider-native formats vary; you needed per-provider handling.
  const response = await model.invoke("Explain AI");
  for (const item of response.content as any[]) {
    if (item.type === "reasoning") {
      // OpenAI-style reasoning
    } else if (item.type === "thinking") {
      // Anthropic-style thinking
    } else if (item.type === "text") {
      // Text
    }
  }
  ```
</CodeGroup>

### Create multimodal messages

<CodeGroup>
  ```typescript v1 (new) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { HumanMessage } from "langchain";

  const message = new HumanMessage({
    contentBlocks: [
      { type: "text", text: "Describe this image." },
      { type: "image", url: "https://example.com/image.jpg" },
    ],
  });
  const res = await model.invoke([message]);
  ```

  ```typescript v0 (old) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { HumanMessage } from "langchain";

  const message = new HumanMessage({
    // Provider-native structure
    content: [
      { type: "text", text: "Describe this image." },
      { type: "image_url", image_url: { url: "https://example.com/image.jpg" } },
    ],
  });
  const res = await model.invoke([message]);
  ```
</CodeGroup>

### Example block types

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { ContentBlock } from "langchain";

const textBlock: ContentBlock.Text = {
  type: "text",
  text: "Hello world",
};

const imageBlock: ContentBlock.Multimodal.Image = {
  type: "image",
  url: "https://example.com/image.png",
  mimeType: "image/png",
};
```

See the content blocks [reference](/oss/javascript/langchain/messages#content-block-reference) for more details.

### Serialize standard content

Standard content blocks are **not serialized** into the `content` attribute by default. If you need to access standard content blocks in the `content` attribute (e.g., when sending messages to a client), you can opt-in to serializing them into `content`.

<CodeGroup>
  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  export LC_OUTPUT_VERSION=v1
  ```

  ```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { initChatModel } from "langchain";

  const model = await initChatModel("gpt-5-nano", {
    outputVersion: "v1",
  });
  ```
</CodeGroup>

<Note>
  Learn more: [Messages](/oss/javascript/langchain/messages#message-content) and [Standard content blocks](/oss/javascript/langchain/messages#standard-content-blocks). See [Multimodal](/oss/javascript/langchain/messages#multimodal) for input examples.
</Note>

***

## Simplified package

The `langchain` package namespace is streamlined to focus on agent building blocks. Legacy functionality has moved to `@langchain/classic`. The new package exposes only the most useful and relevant functionality.

### Exports

The v1 package includes:

| Module      | What's available                              | Notes                              |
| ----------- | --------------------------------------------- | ---------------------------------- |
| Agents      | `createAgent`, `AgentState`                   | Core agent creation functionality  |
| Messages    | Message types, content blocks, `trimMessages` | Re-exported from `@langchain/core` |
| Tools       | `tool`, tool classes                          | Re-exported from `@langchain/core` |
| Chat models | `initChatModel`, `BaseChatModel`              | Unified model initialization       |

### `@langchain/classic`

If you use legacy chains, the indexing API, or functionality previously re-exported from `@langchain/community`, install `@langchain/classic` and update imports:

<CodeGroup>
  ```bash npm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  npm install @langchain/classic
  ```

  ```bash pnpm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  pnpm install @langchain/classic
  ```

  ```bash yarn theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  yarn add @langchain/classic
  ```

  ```bash bun theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  bun add @langchain/classic
  ```
</CodeGroup>

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
// v1 (new)
import { ... } from "@langchain/classic";
import { ... } from "@langchain/classic/chains";

// v0 (old)
import { ... } from "langchain";
import { ... } from "langchain/chains";
```

***

## Breaking changes

### Dropped Node 18 support

All LangChain packages now require **Node.js 20 or higher**. Node.js 18 reached [end of life](https://nodejs.org/en/about/releases/) in March 2025.

### New build outputs

Builds for all langchain packages now use a bundler based approach instead of using raw typescript outputs. If you were importing files from the `dist/` directory (which is not recommended), you will need to update your imports to use the new module system.

### Legacy code moved to `@langchain/classic`

Legacy functionality outside the focus of standard interfaces and agents has been moved to the [`@langchain/classic`](https://www.npmjs.com/package/@langchain/classic) package. See the [Simplified package](#simplified-package) section for details on what's available in the core `langchain` package and what moved to `@langchain/classic`.

### Removal of deprecated APIs

Methods, functions, and other objects that were already deprecated and slated for removal in 1.0 have been deleted.

<Accordion title="View removed deprecated APIs">
  The following deprecated APIs have been removed in v1:

  #### Core functionality

  * `TraceGroup` - Use LangSmith tracing instead
  * `BaseDocumentLoader.loadAndSplit` - Use `.load()` followed by a text splitter
  * `RemoteRunnable` - No longer supported

  #### Prompts

  * `BasePromptTemplate.serialize` and `.deserialize` - Use JSON serialization directly
  * `ChatPromptTemplate.fromPromptMessages` - Use `ChatPromptTemplate.fromMessages`

  #### Retrievers

  * `BaseRetrieverInterface.getRelevantDocuments` - Use `.invoke()` instead

  #### Runnables

  * `Runnable.bind` - Use `.bindTools()` or other specific binding methods
  * `Runnable.map` - Use `.batch()` instead
  * `RunnableBatchOptions.maxConcurrency` - Use `maxConcurrency` in the config object

  #### Chat models

  * `BaseChatModel.predictMessages` - Use `.invoke()` instead
  * `BaseChatModel.predict` - Use `.invoke()` instead
  * `BaseChatModel.serialize` - Use JSON serialization directly
  * `BaseChatModel.callPrompt` - Use `.invoke()` instead
  * `BaseChatModel.call` - Use `.invoke()` instead

  #### LLMs

  * `BaseLLMParams.concurrency` - Use `maxConcurrency` in the config object
  * `BaseLLM.call` - Use `.invoke()` instead
  * `BaseLLM.predict` - Use `.invoke()` instead
  * `BaseLLM.predictMessages` - Use `.invoke()` instead
  * `BaseLLM.serialize` - Use JSON serialization directly

  #### Streaming

  * `createChatMessageChunkEncoderStream` - Use `.stream()` method directly

  #### Tracing

  * `BaseTracer.runMap` - Use LangSmith tracing APIs
  * `getTracingCallbackHandler` - Use LangSmith tracing
  * `getTracingV2CallbackHandler` - Use LangSmith tracing
  * `LangChainTracerV1` - Use LangSmith tracing

  #### Memory and storage

  * `BaseListChatMessageHistory.addAIChatMessage` - Use `.addMessage()` with `AIMessage`
  * `BaseStoreInterface` - Use specific store implementations

  #### Utilities

  * `getRuntimeEnvironmentSync` - Use async `getRuntimeEnvironment()`
</Accordion>

***

<div className="source-links">
  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
  </Callout>

  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/oss/javascript/migrate/langchain-v1.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>
</div>
