Our position: we are Geonode and we sell proxies, which have nothing to do with LLM frameworks. We make nothing whichever you choose, which makes this a comparison written by someone with no stake in the outcome — an unusual position in a category where most comparisons come from one of the vendors. All versions, licences and repository activity below were checked in September 2026.
Why People Look for Alternatives
Worth naming the actual complaints, because they determine which alternative helps.
Abstraction depth. Debugging a chain frequently means reading framework source to work out what prompt was actually sent. The indirection that makes a demo short makes production incidents long.
API churn. The framework has moved substantially over its life, and tutorials date quickly. Code written against one major version needs revisiting.
Dependency weight. A large surface area brings a large dependency tree, which matters in constrained deployments and in security review.
Doing too much. Chains, agents, memory, retrieval, tooling, evaluation. Most projects need two of those and inherit all of them.
Note that none of these complaints is about the ideas. LangChain's abstractions are reasonable descriptions of the problem space, which is precisely why they were copied. The complaints are about the cost of adopting a whole framework to use part of one.
It is also worth stating that the project is not standing still: langchain is at 1.3.18 and langchain-core at 1.6.1, both released in late August 2026, MIT licensed, with the repository among the most active in the category. Much criticism of it describes an older version.
The Landscape
All figures from PyPI and the projects' own repositories, checked September 2026.
| Project | Latest | Licence | Focus |
|---|---|---|---|
| LangChain | 1.3.18 | MIT | General-purpose composition |
| LangGraph | 1.2.11 | MIT | Stateful, multi-actor workflows |
| LlamaIndex | 0.14.24 | MIT | Data indexing and retrieval |
| Haystack | 3.1.0 | Apache-2.0 | Production pipelines |
| DSPy | 3.3.1 | MIT | Programmatic prompt optimisation |
| Semantic Kernel | 1.44.1 | MIT | Enterprise, multi-language |
| Pydantic AI | 2.37.0 | MIT | Type-safe agents |
| Instructor | 1.16.0 | MIT | Structured outputs only |
All actively developed — every one of these was pushed to within days of checking. All permissively licensed. The differences are in scope and philosophy rather than in viability.
LlamaIndex: Retrieval First
The closest general-purpose alternative, and it arrives from a different direction.
Where LangChain started from composing LLM calls, LlamaIndex started from connecting LLMs to your data — its own summary is "interface between LLMs and your data". That origin shows in what it does well: document loading from a very wide range of sources, chunking strategies, index construction, and retrieval patterns beyond simple top-k similarity.
Choose it when retrieval quality is the hard part of your problem. Its index abstractions and query engines are more sophisticated than the equivalent in a general framework, and the loader ecosystem is broad enough that connecting to an unusual source is usually a one-liner.
The reservation is the same shape as LangChain's: it has grown into a general framework, so adopting it for retrieval brings agents, workflows and tooling you may not want.
Haystack: Production Pipelines
Deepset's framework, and the most explicitly production-oriented of the group — it describes itself as a framework "to build customizable, production-ready LLM applications".
Its distinguishing property is that pipelines are explicit graphs of components with declared inputs and outputs, serialisable to YAML. That makes what runs inspectable in a way that method-chaining does not, and it makes a pipeline something you can version, diff and review.
Choose it when you are building something that will be operated rather than demonstrated — where the ability to see the pipeline structure, serialise it, and reason about it in review matters more than the shortest path to a working prototype.
It is also the only Apache-2.0 project on this list rather than MIT, which is a distinction without much practical difference — both are permissive — but occasionally matters to a legal review with a preference.
DSPy: A Genuinely Different Idea
The most interesting alternative, and the one that is not a variation on the others.
DSPy's premise is that hand-written prompts are the wrong abstraction. You declare what a module should do in terms of inputs and outputs, and the framework optimises the prompts — including few-shot examples — against a metric you define.
The consequence is a different development loop. Instead of iterating on prompt wording by hand, you build an evaluation set, define a metric, and let the optimiser search. That converts prompt engineering from a craft into something closer to a training procedure.
Choose it when you have a task with measurable quality, an evaluation set, and enough volume that systematic optimisation pays off. Classification, extraction and structured reasoning all fit.
Do not choose it when you cannot define a metric, or when the task is a one-off. The whole approach rests on being able to score outputs automatically, and building that evaluation set is the real work.
At 37,000 stars and active development, it is well past the experimental stage — but it asks more of you upfront than any other option here.
Pydantic AI and Instructor: Narrow on Purpose
Two projects that solve less, deliberately.
Instructor does one thing: structured outputs. You define a Pydantic model, and it handles the schema, validation and retry-on-invalid loop. That is the whole library.
An enormous share of LLM application code is "get valid JSON matching this shape out of a model", and Instructor is a complete answer to it in a few lines with essentially no framework overhead. If that is your requirement, adopting a general framework to obtain it is a poor trade.
Pydantic AI is broader — an agent framework "the Pydantic way" — bringing type safety, dependency injection and structured outputs to agent construction. It is younger than the others and growing quickly, and it appeals particularly to teams already invested in Pydantic and type checking.
Choose these when your problem is well defined and you would rather have a library than a framework. The distinction matters: a library is something you call, a framework is something that calls you, and the second is much harder to leave.
Semantic Kernel: Enterprise and Multi-Language
Microsoft's framework, and the one to consider when Python is not the whole story.
Its distinguishing features are first-class support across .NET, Python and Java, and an architecture built around plugins and planners that maps onto enterprise integration patterns.
Choose it when you are in a .NET shop, when you need the same concepts across several languages, or when your organisation's platform decisions point that way. Those are real constraints and they are frequently decisive regardless of technical merit.
For a Python-only project with no such constraint, the Python-native options generally have more momentum in the ecosystem.
LangGraph: The Alternative Within LangChain
Worth separating out, because it is often what people actually want when they say they want an alternative.
LangGraph — from the same team, MIT licensed, at 1.2.11 — describes itself as being for "building stateful, multi-actor applications with LLMs". It is a graph execution model with explicit state, rather than a chain abstraction.
The distinction matters because most complaints about LangChain concern hidden control flow. LangGraph makes control flow the thing you write: nodes, edges, conditional transitions and a state object you define. That is considerably more legible when something goes wrong at three in the morning.
Choose it when your application has genuine state, branching or cycles — an agent that loops, a workflow with approval steps, anything where "what happens next" depends on what happened before. It can be used without adopting the rest of LangChain.
No Framework: The Case For
The option most comparison articles omit, and the right answer for a substantial share of applications.
Model provider SDKs are good now. Calling one directly is a few lines, and it is completely transparent:
response = client.messages.create(
model=MODEL,
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
What you give up: provider abstraction, prebuilt integrations, ready-made retrieval components, and the agent loop.
What you gain: you can read your own code. The prompt sent is the prompt in the file. Debugging is reading a request and a response rather than tracing through framework layers. Your dependency tree is one SDK. And upgrades are the provider's release notes rather than a framework's migration guide.
A reasonable middle position: use narrow libraries for specific problems — Instructor for structured outputs, a vector database client for retrieval, an HTTP client for tool calls — and write the orchestration yourself. Orchestration is usually fifty lines, and fifty lines you wrote is easier to maintain than a framework you did not.
When a framework genuinely earns its place: when you need many provider integrations, when you are building agents with complex tool use and want the loop handled, when a team benefits from shared conventions, or when your prototyping speed matters more than your production legibility. Those are real reasons and they apply to real projects.
The failure mode to avoid is adopting a framework for the demo and discovering in production that you cannot see what it does.
Migrating Away From a Framework
If you already have a LangChain application and are considering a move, the work is more predictable than it looks — and the sequence matters.
Find out what it is actually sending first. Before changing anything, capture the real prompts and parameters. Most frameworks expose a callback or a debug flag for this, and setting it produces the single most useful artefact of the whole exercise: a record of what your application does, expressed as HTTP requests rather than as method calls. Half the time this alone reveals that the framework is doing something you did not intend.
Move one component at a time, not the whole application. The pieces are separable. Replace the retrieval step with direct vector database client calls while leaving the rest in place; confirm output quality is unchanged; then move the next piece. A big-bang rewrite conflates "the new code is wrong" with "the new code is different", and you lose the ability to tell which.
Keep an output comparison harness. Run both implementations against the same inputs and diff the results. Retrieval and generation are non-deterministic enough that "it looks fine" is not evidence, and a hundred paired outputs will show you a regression that spot-checking will not.
Expect the prompt templates to be the difficult part. Framework prompt templates frequently include boilerplate you did not write and may not have read — formatting instructions, output parsers, few-shot scaffolding. Reproducing behaviour means reproducing those, which is why capturing the actual sent prompts comes first.
And be honest about whether it is worth it. A working application that you find slightly opaque is not obviously worse than a rewritten one you understand and that has new bugs. The case for migrating is strong when the framework is actively costing you — debugging time, upgrade churn, dependency conflicts — and weak when the motivation is aesthetic. Rewrites justified by taste have a poor record.
The realistic middle path for most teams is to stop adding new framework surface rather than removing existing surface. New components written directly, old ones left alone until they need changing anyway.
How to Choose
A short procedure that resolves most cases.
Write down what you actually need. Structured outputs? Retrieval? Multi-step agents with tools? Provider switching? Most projects need one or two of these. Adopting a general framework for one is where the regret comes from.
Try it without a framework first. Half a day writing directly against an SDK tells you what the hard part of your problem really is, and that answer usually points at a specific library rather than a general framework.
Match the tool to the hard part. Retrieval quality points at LlamaIndex. Measurable task quality with an evaluation set points at DSPy. Structured extraction points at Instructor or Pydantic AI. Stateful multi-step workflows point at LangGraph or Haystack. Enterprise multi-language points at Semantic Kernel.
Weigh the exit cost. How much of your code would change if you removed it? A library you call is cheap to leave; a framework that owns your control flow is not. That question is worth asking before adoption rather than after.
And do not choose on popularity alone. Every option here is actively maintained and permissively licensed. Ecosystem size matters for finding examples, and it is not the same as fitness for your problem.
People Also Ask
What is the best alternative to LangChain?
It depends on which part you need. LlamaIndex for retrieval-heavy applications, Haystack for inspectable production pipelines, DSPy for tasks with measurable quality, Instructor or Pydantic AI for structured outputs, LangGraph for stateful workflows. For many applications, calling the provider SDK directly is the best option.
Is LangChain still maintained?
Very much so. langchain was at 1.3.18 and langchain-core at 1.6.1 in late August 2026, both MIT licensed, with the repository among the most active in the category. Much of the criticism circulating describes earlier versions.
Do I need a framework to build with LLMs?
No. Provider SDKs are straightforward, and a direct call is a few lines with complete transparency about what is sent. Frameworks earn their place with many integrations, complex agent loops or shared team conventions — and cost you the ability to see what is happening.
LangChain or LlamaIndex?
LlamaIndex if retrieval is the hard part: its document loaders, chunking strategies and index abstractions are more developed. LangChain if you need broad composition across many providers and tools. Both have grown into general frameworks, so the distinction is smaller than it once was.
What is DSPy and how is it different?
It treats prompts as parameters to be optimised rather than text to be written. You declare inputs and outputs, define a metric, and the framework optimises prompts and few-shot examples against your evaluation set. It requires an evaluation set, which is the real cost and also the real benefit.
Is LangGraph a LangChain alternative?
It is from the same team and can be used independently. It replaces chain abstractions with an explicit graph of nodes, edges and state, which addresses the most common complaint about LangChain — that control flow is hidden. For stateful or branching applications it is frequently what people actually wanted.
Which LLM framework is best for production?
Haystack is the most explicitly production-oriented, with serialisable pipelines you can version and review. LangGraph suits stateful workflows. But the most production-friendly choice is often the least framework — code you can read at three in the morning beats abstractions you have to trace through.
Are these frameworks free and open source?
All of them. LangChain, LangGraph, LlamaIndex, DSPy, Semantic Kernel, Pydantic AI and Instructor are MIT licensed; Haystack is Apache-2.0. All are permissive with no copyleft restrictions, and all were actively developed as of September 2026.
Wrapping Up
The framework question is really a scope question. Every project here is well maintained and permissively licensed, so the decision is not about quality — it is about how much of your application's control flow you want to hand over.
Hand over a lot and you get speed to a first working version, integrations you did not write, and an agent loop you did not have to think about. Hand over a little and you get code you can read, a dependency tree you can audit, and debugging that consists of looking at a request and a response.
The habit worth building is to spend half a day without a framework first. That tells you what the hard part of your problem actually is — and it is usually retrieval quality, or structured output validity, or evaluation, none of which a general framework solves better than a focused library does.
Then pick for that specific problem. LlamaIndex for retrieval, DSPy where you can measure quality, Instructor or Pydantic AI for structured outputs, LangGraph or Haystack where state and inspectability matter, Semantic Kernel where the platform decision is already made. And keep the exit cost in view, because the difference between a library and a framework is not what it does for you — it is how much of your code has to change when you stop using it.
