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 packagesSupported providers built in, one 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-drivenIn production use at Juspay

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 supported 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 streaming API across supported 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​