mrkeyoor.com_
Wed 05 Aug 05:04 UTC
npmAI / MLupdated 05 Aug 2026

langchain

langchain is the JavaScript/TypeScript framework for building LLM applications and agents. Version 1.x centers on createAgent: a tool-calling loop that takes a model (as a 'provider:model' string or an instance), a set of tools, and optional middleware, and runs the model against those tools until the task completes. It adds structured output, streaming, and thread-level memory, with LangGraph underneath for state and persistence, and one interface across OpenAI, Anthropic, Google, Ollama, and many other providers.

Verdict

v1 finally gives LangChain.js a focused core: createAgent is a capable agent loop with real provider breadth. If your app is a few direct model calls, a provider SDK and fifty lines of your own code remain the simpler, more debuggable choice.

API stability2/5The 0.x line saw repeated deprecations and the 1.0 release rewrote the core API around createAgent. 1.x has been consistent so far, but it is young and the project's history is one of moving abstractions.
Docs4/5docs.langchain.com is thorough, with per-provider runnable examples for agents, streaming, and memory. The catch is content spread across LangChain, LangGraph, and LangSmith, and a web full of stale 0.x tutorials.
Maintenance5/5Developed by LangChain, Inc. with near-daily pushes; the repo was updated the day of this review and 1.x has moved from 1.0 to 1.5 in a matter of months.
Ecosystem4/5Large integration catalog of model providers, vector stores, and tools, plus LangGraph and LangSmith. Smaller than the Python ecosystem, and some community integrations lag core releases.

Use it if

  • You swap or compare model providers and want one calling convention instead of rewriting against each vendor SDK
  • You need an agent loop with tools, conversation memory, and structured output and do not want to hand-build the loop, retries, and message plumbing
  • You expect to grow into LangGraph orchestration or LangSmith tracing, which plug into the same stack
Skip it if

Setup reality

You install langchain plus @langchain/core (a peer dependency) plus one provider package like @langchain/openai, and the docs quickstart assumes Node 22+. The classic install trap is peer-dependency version mismatch between @langchain/core and provider packages after a partial upgrade; align them or you get confusing type and runtime errors. Provider API keys come from environment variables. Expect to spend time orienting in docs that span LangChain, LangGraph, and LangSmith, and to distrust any tutorial written before the 1.0 rewrite.

Patterns

Create and invoke a basic agentcreate-agent

import { createAgent } from 'langchain';

const agent = createAgent({
  model: 'openai:gpt-5.5',
  tools: [],
});

const result = await agent.invoke({
  messages: [{ role: 'user', content: 'What is 6 times 7?' }],
});

The 'provider:model' string needs the matching provider package installed and its API key set as an env var.

Define a tool with a zod schemadefine-tool

import { createAgent, tool } from 'langchain';
import * as z from 'zod';

const search = tool(({ query }) => `Results for: ${query}`, {
  name: 'search',
  description: 'Search for information',
  schema: z.object({ query: z.string() }),
});

const agent = createAgent({ model: 'openai:gpt-5.5', tools: [search] });

The description is what the model reads to decide when to call the tool; vague descriptions produce bad tool choice.

Set a system prompt on the agentsystem-prompt

import { createAgent } from 'langchain';

const agent = createAgent({
  model: 'anthropic:claude-sonnet-4-6',
  tools,
  systemPrompt: 'You are a helpful assistant. Be concise and accurate.',
});

systemPrompt is a plain string; for dynamic prompts based on state you reach for middleware instead.

Get validated structured outputstructured-output

import { createAgent } from 'langchain';
import * as z from 'zod';

const Answer = z.object({ summary: z.string(), confidence: z.number() });

const agent = createAgent({
  model: 'openai:gpt-5.5',
  tools,
  responseFormat: Answer,
});

const result = await agent.invoke({
  messages: [{ role: 'user', content: 'Summarize AI trends' }],
});
result.structuredResponse; // { summary, confidence }

The parsed object lives on result.structuredResponse, not in the message list.

Stream tokens as they generatestream-tokens

for await (const [token, metadata] of await agent.stream(
  { messages: [{ role: 'user', content: 'what is the weather in sf' }] },
  { streamMode: 'messages' },
)) {
  console.log(metadata.langgraph_node, token.contentBlocks);
}

streamMode 'messages' yields token chunks; 'values' yields the full state after each step, which is much chattier.

Keep conversation history across turnsconversation-memory

import { createAgent } from 'langchain';
import { MemorySaver } from '@langchain/langgraph';

const agent = createAgent({
  model: 'openai:gpt-5.5',
  tools: [],
  checkpointer: new MemorySaver(),
});

const config = { configurable: { thread_id: crypto.randomUUID() } };

await agent.invoke({ messages: [{ role: 'user', content: 'Weather in SF?' }] }, config);
// same thread_id = the agent remembers the previous turn
await agent.invoke({ messages: [{ role: 'user', content: 'And tomorrow?' }] }, config);

MemorySaver is in-process only; use a persistent checkpointer in production or history dies with the process.

Read the final text reply from a resultread-agent-reply

const result = await agent.invoke({
  messages: [{ role: 'user', content: 'Hello' }],
});

const last = result.messages.at(-1);
console.log(last?.content);

result.messages contains the whole run including tool calls and tool results, not just the final answer.

Call a chat model without an agentdirect-model-call

import { ChatOpenAI } from '@langchain/openai';

const model = new ChatOpenAI({ model: 'gpt-5.5' });
const res = await model.invoke([
  { role: 'system', content: 'You translate English to French.' },
  { role: 'user', content: 'Good morning' },
]);
console.log(res.content);

For a single completion with no tools, calling the model directly skips the whole agent loop and its overhead.

Build a reusable prompt template chainprompt-template

import { ChatPromptTemplate } from '@langchain/core/prompts';
import { ChatOpenAI } from '@langchain/openai';

const prompt = ChatPromptTemplate.fromMessages([
  ['system', 'You translate English to {language}.'],
  ['user', '{text}'],
]);

const chain = prompt.pipe(new ChatOpenAI({ model: 'gpt-5.5' }));
const out = await chain.invoke({ language: 'French', text: 'Hello' });

Templates live in @langchain/core; single curly braces are template variables, so escape literal braces by doubling them.

Alternatives

PackageRegistryPick it when
ainpmYou want a leaner TypeScript SDK with first-class streaming UI hooks, especially in Next.js
@langchain/langgraphnpmYou need custom multi-step orchestration beyond what the createAgent loop offers
llamaindexnpmYour app is primarily retrieval over your own documents rather than a general agent