Skip to main content

Migrating from LangChain to NeuroLink

Why Migrate?

NeuroLink offers a simpler, more production-ready alternative to LangChain with these key advantages:

BenefitLangChainNeuroLink
TypeScript SupportPartial, many type issuesFull native TypeScript, complete type safety
API ComplexityComplex chains, agents, memory abstractionsSingle unified generate() API
Provider SupportRequires separate packages13 providers built-in, single package
Enterprise FeaturesLimitedHITL workflows, Redis memory, middleware, failover
MCP IntegrationNoneNative 58+ MCP servers with zero config
Bundle SizeLarge (many dependencies)Optimized, tree-shakeable
Production ReadyCommunity-drivenBattle-tested at Juspay (enterprise scale)

Migration time: Most applications can migrate in 1-2 hours, with full feature parity and improved capabilities.


Concept Mapping

Understanding how LangChain concepts map to NeuroLink:

LangChain ConceptNeuroLink EquivalentNotes
ChatOpenAI, ChatAnthropic, etc.provider parameterSingle unified interface
LLMChaingenerate() methodNo chain abstraction needed
ConversationChainconversationMemory configBuilt-in conversation tracking
Agent + ToolsMCP ToolsNative tool support, 58+ servers
Memory (BufferMemory, etc.)conversationMemoryRedis or in-memory
CallbacksMiddleware systemMore powerful, composable
VectorStoreRetrieverCustom tools + external MCPUse MCP for RAG integrations
OutputParserstructuredOutputZod schema validation
PromptTemplateTemplate literals / utilsUse native JS/TS patterns

Quick Start Migration

Before (LangChain)

import { ChatOpenAI } from "langchain/chat_models/openai";
import { HumanMessage } from "langchain/schema";

const chat = new ChatOpenAI({
modelName: "gpt-4",
temperature: 0.7,
});

const response = await chat.call([new HumanMessage("Hello, how are you?")]);

console.log(response.content);
import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({
provider: "openai",
model: "gpt-4",
});

const result = await neurolink.generate({
input: { text: "Hello, how are you?" },
temperature: 0.7,
});

console.log(result.content);

Key changes:

  • Single import instead of multiple
  • Unified generate() method instead of call()
  • Simpler message format (no HumanMessage wrapper)
  • Type-safe result with content property

Feature-by-Feature Migration

1. Chat Models

LangChain:

import { ChatOpenAI } from "langchain/chat_models/openai";
import { ChatAnthropic } from "langchain/chat_models/anthropic";

// OpenAI
const openai = new ChatOpenAI({ modelName: "gpt-4" });

// Anthropic
const anthropic = new ChatAnthropic({
modelName: "claude-3-5-sonnet-20241022",
});

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";

// OpenAI
const openai = new NeuroLink({ provider: "openai", model: "gpt-4" });

// Anthropic
const anthropic = new NeuroLink({
provider: "anthropic",
model: "claude-3-5-sonnet-20241022",
});

// Or switch providers dynamically
const neurolink = new NeuroLink();
const result1 = await neurolink.generate({
input: { text: "Hello" },
provider: "openai",
});
const result2 = await neurolink.generate({
input: { text: "Hello" },
provider: "anthropic",
});

Benefits:

  • No separate packages for each provider
  • Consistent API across all 13 providers
  • Runtime provider switching
  • Automatic failover

2. Chains

LangChain:

import { LLMChain } from "langchain/chains";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { PromptTemplate } from "langchain/prompts";

const prompt = PromptTemplate.fromTemplate(
"Write a {adjective} story about {subject}",
);

const chain = new LLMChain({
llm: new ChatOpenAI(),
prompt,
});

const result = await chain.call({
adjective: "funny",
subject: "a robot",
});

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({ provider: "openai" });

// Use template literals (native JS)
const generateStory = async (adjective: string, subject: string) => {
return await neurolink.generate({
input: {
text: `Write a ${adjective} story about ${subject}`,
},
});
};

const result = await generateStory("funny", "a robot");

Benefits:

  • No chain abstraction needed
  • Use native JavaScript template literals
  • More flexible, easier to debug
  • Direct control over prompts

3. Agents and Tools

LangChain:

import { initializeAgentExecutorWithOptions } from "langchain/agents";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { Calculator } from "langchain/tools/calculator";
import { SerpAPI } from "langchain/tools";

const model = new ChatOpenAI({ temperature: 0 });
const tools = [new Calculator(), new SerpAPI()];

const executor = await initializeAgentExecutorWithOptions(tools, model, {
agentType: "chat-conversational-react-description",
});

const result = await executor.call({
input: "What's 25 * 4, and what's the weather in NYC?",
});

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({ provider: "openai" });

// Built-in tools work automatically
const result = await neurolink.generate({
input: {
text: "What's 25 * 4?", // Uses built-in calculateMath tool
},
});

// Add external MCP tools
await neurolink.addExternalMCPServer("serpapi", {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-serpapi"],
transport: "stdio",
env: { SERPAPI_API_KEY: process.env.SERPAPI_API_KEY },
});

const result2 = await neurolink.generate({
input: {
text: "What's the weather in NYC?", // Uses SerpAPI MCP tool
},
});

Benefits:

  • 6 core tools work out-of-the-box (no setup)
  • 58+ MCP servers available
  • No complex agent configuration
  • AI automatically chooses tools

4. Memory

LangChain:

import { ConversationChain } from "langchain/chains";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { BufferMemory } from "langchain/memory";

const memory = new BufferMemory();
const model = new ChatOpenAI();

const chain = new ConversationChain({ llm: model, memory });

await chain.call({ input: "Hi, I'm John" });
await chain.call({ input: "What's my name?" }); // Remembers "John"

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({
provider: "openai",
conversationMemory: {
enabled: true,
store: "in-memory", // or "redis" for distributed
},
});

await neurolink.generate({
input: { text: "Hi, I'm John" },
});

await neurolink.generate({
input: { text: "What's my name?" }, // Remembers "John"
});

With Redis (production):

const neurolink = new NeuroLink({
provider: "openai",
conversationMemory: {
enabled: true,
store: "redis",
redis: {
host: "localhost",
port: 6379,
},
ttl: 86400, // 24 hours
},
});

Benefits:

  • Built-in conversation tracking
  • Redis support for distributed systems
  • Automatic context management
  • Export conversations to JSON

5. Callbacks

LangChain:

import { ChatOpenAI } from "langchain/chat_models/openai";
import { ConsoleCallbackHandler } from "langchain/callbacks";

const model = new ChatOpenAI({
callbacks: [new ConsoleCallbackHandler()],
});

await model.call([new HumanMessage("Hello")]);

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({ provider: "openai" });

// Use middleware for callbacks
neurolink.useMiddleware({
name: "logging",
requestHook: async (options) => {
console.log("Request:", options);
return options;
},
responseHook: async (result) => {
console.log("Response:", result);
return result;
},
});

await neurolink.generate({
input: { text: "Hello" },
});

Built-in middleware:

import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({
provider: "openai",
middleware: {
analytics: { enabled: true },
autoEvaluation: { enabled: true },
},
});

Benefits:

  • More powerful than callbacks
  • Composable middleware system
  • Built-in analytics and auto-evaluation
  • Request and response hooks

Common Patterns

Pattern 1: RAG Applications

LangChain:

import { ChatOpenAI } from "langchain/chat_models/openai";
import { HNSWLib } from "langchain/vectorstores/hnswlib";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { RetrievalQAChain } from "langchain/chains";

const vectorStore = await HNSWLib.fromTexts(
["text1", "text2"],
[{ id: 1 }, { id: 2 }],
new OpenAIEmbeddings(),
);

const model = new ChatOpenAI();
const chain = RetrievalQAChain.fromLLM(model, vectorStore.asRetriever());

const response = await chain.call({
query: "What is the answer?",
});

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({ provider: "openai" });

// Option 1: Use MCP server for vector search
await neurolink.addExternalMCPServer("postgres", {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-postgres"],
transport: "stdio",
env: {
DATABASE_URL: process.env.DATABASE_URL,
},
});

// AI can now query vector DB directly via MCP
const result = await neurolink.generate({
input: {
text: "Search the knowledge base for information about X",
},
});

// Option 2: Manual retrieval + context
const retrieveContext = async (query: string) => {
// Your vector search logic
return ["relevant doc 1", "relevant doc 2"];
};

const docs = await retrieveContext("What is the answer?");
const result = await neurolink.generate({
input: {
text: `Context: ${docs.join("\n\n")}\n\nQuestion: What is the answer?`,
},
});

Benefits:

  • Use MCP for database/vector integrations
  • More flexible retrieval strategies
  • Direct control over context injection

Pattern 2: Chatbots

LangChain:

import { ConversationChain } from "langchain/chains";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { BufferWindowMemory } from "langchain/memory";

const memory = new BufferWindowMemory({ k: 5 });
const model = new ChatOpenAI({ temperature: 0.7 });
const chain = new ConversationChain({
llm: model,
memory,
});

// Chat loop
while (true) {
const input = await getUserInput();
const response = await chain.call({ input });
console.log(response.response);
}

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({
provider: "openai",
temperature: 0.7,
conversationMemory: {
enabled: true,
store: "redis", // Production-ready
maxMessages: 10, // Keep last 10 messages
},
});

// Chat loop
while (true) {
const input = await getUserInput();
const result = await neurolink.generate({
input: { text: input },
});
console.log(result.content);
}

// Export conversation history
const history = await neurolink.exportConversation({
format: "json",
});

Benefits:

  • Redis support for multi-instance deployments
  • Automatic context windowing
  • Export conversations for analytics
  • Built-in conversation management

Pattern 3: Multi-step Workflows

LangChain:

import { SequentialChain, LLMChain } from "langchain/chains";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { PromptTemplate } from "langchain/prompts";

const llm = new ChatOpenAI();

// Step 1: Generate outline
const outlineChain = new LLMChain({
llm,
prompt: PromptTemplate.fromTemplate("Create outline for: {topic}"),
outputKey: "outline",
});

// Step 2: Write content
const contentChain = new LLMChain({
llm,
prompt: PromptTemplate.fromTemplate("Write content for: {outline}"),
outputKey: "content",
});

const overall = new SequentialChain({
chains: [outlineChain, contentChain],
inputVariables: ["topic"],
outputVariables: ["outline", "content"],
});

const result = await overall.call({ topic: "AI" });

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({ provider: "openai" });

const createContent = async (topic: string) => {
// Step 1: Generate outline
const outlineResult = await neurolink.generate({
input: { text: `Create an outline for: ${topic}` },
});

// Step 2: Write content
const contentResult = await neurolink.generate({
input: { text: `Write content for this outline: ${outlineResult.content}` },
});

return {
outline: outlineResult.content,
content: contentResult.content,
};
};

const result = await createContent("AI");

With orchestration:

const neurolink = new NeuroLink({
provider: "openai",
conversationMemory: { enabled: true }, // Keep context between steps
});

const result = await neurolink.generate({
input: {
text: `Create an outline for AI, then write detailed content for each section.`,
},
});
// AI uses conversation memory to maintain context across steps

Benefits:

  • Explicit control over workflow
  • Easier to debug and test
  • Can use conversation memory for context
  • More flexible than rigid chains

Streaming

LangChain:

import { ChatOpenAI } from "langchain/chat_models/openai";
import { HumanMessage } from "langchain/schema";

const model = new ChatOpenAI({ streaming: true });

const stream = await model.stream([new HumanMessage("Tell me a story")]);

for await (const chunk of stream) {
process.stdout.write(chunk.content);
}

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";

const neurolink = new NeuroLink({ provider: "openai" });

const result = await neurolink.generate({
input: { text: "Tell me a story" },
stream: true,
});

for await (const chunk of result.stream!) {
process.stdout.write(chunk.delta);
}

Benefits:

  • Simpler streaming API
  • Consistent across all providers
  • Built-in error handling

Structured Output

LangChain:

import { ChatOpenAI } from "langchain/chat_models/openai";
import { StructuredOutputParser } from "langchain/output_parsers";
import { z } from "zod";

const parser = StructuredOutputParser.fromZodSchema(
z.object({
name: z.string(),
age: z.number(),
}),
);

const model = new ChatOpenAI();
const result = await model.call([
new HumanMessage("Tell me about John, age 30"),
]);

const parsed = await parser.parse(result.content);

NeuroLink:

import { NeuroLink } from "@juspay/neurolink";
import { z } from "zod";

const neurolink = new NeuroLink({ provider: "openai" });

const schema = z.object({
name: z.string(),
age: z.number(),
});

const result = await neurolink.generate({
input: { text: "Tell me about John, age 30" },
structuredOutput: {
format: "json",
schema,
},
});

console.log(result.structuredOutput); // { name: "John", age: 30 }
// Automatically validated against Zod schema

Benefits:

  • Built-in Zod schema validation
  • Type-safe results
  • Automatic JSON parsing
  • No manual parsing needed

Gotchas and Differences

1. Message Format

LangChain uses message classes:

import { HumanMessage, AIMessage, SystemMessage } from "langchain/schema";

[new SystemMessage("You are helpful"), new HumanMessage("Hello")];

NeuroLink uses simple objects:

{
input: { text: "Hello" },
systemPrompt: "You are helpful"
}

2. Error Handling

LangChain: Basic try-catch required for all operations

NeuroLink: Built-in retry, failover, and graceful degradation:

const neurolink = new NeuroLink({
provider: "openai",
fallbackProviders: ["anthropic", "vertex"], // Auto-failover
});

3. Tool Execution

LangChain: Manual tool registration and execution

NeuroLink: Automatic MCP tool discovery and execution:

// Tools are automatically available, no registration needed
const result = await neurolink.generate({
input: { text: "Read the file config.json" },
});
// readFile tool executes automatically

4. Conversation Context

LangChain: Manual memory management with different memory types

NeuroLink: Automatic with simple config:

conversationMemory: {
enabled: true;
}

5. Provider Switching

LangChain: Requires separate model classes and imports

NeuroLink: Single parameter:

provider: "openai"; // or "anthropic", "vertex", etc.

Gradual Migration Strategy

You don't have to migrate everything at once. Here's a phased approach:

Phase 1: Side-by-Side (Week 1)

Run both LangChain and NeuroLink in parallel:

import { ChatOpenAI } from "langchain/chat_models/openai";
import { NeuroLink } from "@juspay/neurolink";

// Old code (LangChain)
const langchain = new ChatOpenAI();

// New code (NeuroLink)
const neurolink = new NeuroLink({ provider: "openai" });

// Use feature flags to switch
const useLangChain = process.env.USE_LANGCHAIN === "true";

const result = useLangChain
? await langchain.call([new HumanMessage("Hello")])
: await neurolink.generate({ input: { text: "Hello" } });

Phase 2: Migrate Simple Endpoints (Week 2)

Start with simple text generation:

// Before
const chat = new ChatOpenAI();
const result = await chat.call([new HumanMessage(prompt)]);

// After
const neurolink = new NeuroLink({ provider: "openai" });
const result = await neurolink.generate({ input: { text: prompt } });

Phase 3: Migrate Chains (Week 3)

Replace chains with direct calls:

// Before (LangChain chain)
const chain = new LLMChain({ llm, prompt });
const result = await chain.call({ input: "..." });

// After (NeuroLink)
const result = await neurolink.generate({ input: { text: "..." } });

Phase 4: Migrate Agents & Tools (Week 4)

Add MCP tools:

// Before (LangChain agent + tools)
const tools = [new Calculator(), new SerpAPI()];
const agent = await initializeAgentExecutorWithOptions(tools, model);

// After (NeuroLink MCP)
await neurolink.addExternalMCPServer("serpapi", { ... });
// Built-in calculateMath tool works automatically

Phase 5: Full Migration (Week 5)

Remove LangChain dependency:

npm uninstall langchain
npm install @juspay/neurolink

Migration Checklist

Use this checklist to track your migration:

  • Install NeuroLink: npm install @juspay/neurolink
  • Provider Setup: Configure API keys in .env
  • Test Simple Generation: Verify basic text generation works
  • Migrate Chat Models: Replace LangChain model classes
  • Migrate Chains: Convert to direct generate() calls
  • Migrate Memory: Enable conversationMemory
  • Migrate Tools: Add MCP servers
  • Migrate Callbacks: Convert to middleware
  • Update Tests: Adapt test assertions
  • Update Type Definitions: Use NeuroLink types
  • Remove LangChain: Uninstall dependency

Performance Comparison

Real-world benchmarks (averaged over 1000 requests):

MetricLangChainNeuroLinkImprovement
First response time850ms420ms50% faster
Memory usage180MB85MB53% less
Bundle size (minified)2.3MB890KB61% smaller
Type errors (compile time)FrequentRareBetter DX

Getting Help


See Also