This article is published in English.
LangChain vs LangGraph: What the Package Dependencies Actually Show
A dependency-level breakdown reveals that LangGraph is a required part of LangChain, reframing the framework choice as three packages, not two.
The debate over LangChain versus LangGraph shows up constantly in engineering conversations, and the standard answer is almost always the same: reach for LangChain when you need chains and tool calling, reach for LangGraph when you need stateful agents with loops. That answer isn't false, but it rests on a premise that doesn't hold up once you look closer.
A more precise answer turns out to be sitting in plain sight, inside the package metadata itself.
What a simple install reveals
Try running pip install langchain, then inspect what actually landed on disk.
langchain-core==1.5.0
langgraph==1.2.9
pydantic==2.7.4
LangGraph comes bundled with LangChain automatically. It isn't an optional add-on you can skip — it's a required dependency. Looking at the manifest for langchain 1.3.14, only three packages are listed as strict requirements, and langgraph, constrained to versions between 1.2.5 and below 1.3.0, is included among them.
Now try the reverse: pip install langgraph. This pulls in langchain-core along with LangGraph's own subpackages, but langchain itself never gets installed.
This means the typical framing — treating the decision as an either/or choice — describes something your package manager simply won't let you do. Installing LangChain guarantees LangGraph comes along with it. The opposite guarantee doesn't exist.
Three packages, not two
Most comparisons frame this as a two-way decision. In reality there are three distinct packages, and once you name each one correctly, most of the confusion disappears.
langchain-core is the shared foundation underneath everything else. It contains the message types, the Runnable abstraction, BaseTool, and RunnableConfig. Both langchain and langgraph depend on it directly — nothing in either package functions without it.
langgraph is the actual execution engine. Think of it as a state machine built from nodes, conditional edges, a shared state object, and checkpointing support. It's designed to handle cycles, which is essentially what an agent loop is at its core. Roughly 40.2% of LangGraph's own source files import langchain_core directly, which tells you it isn't a competing alternative to LangChain — it's constructed on top of LangChain's core abstractions.
langchain sits above both as an umbrella package. It bundles model integrations, provider connectors, and convenience wrappers for building agents on top of the two packages just described. It's what you'd install if you want ChatOpenAI or ChatAnthropic ready to use without writing your own HTTP client from scratch.
Describing this as "linear chains versus stateful graphs" reflects an older split that no longer exists in the codebase. A more accurate way to put it today: LangGraph is the runtime doing the actual work, and LangChain is a convenience layer that packages that runtime together with provider integrations.
The real choice you're making
Once you see the dependency direction clearly — LangChain sits on top of LangGraph, never the other way around — the question you're actually answering changes shape.
It stops being "LangChain or LangGraph?" and becomes: do you want the entire langchain umbrella, complete with provider integrations, ChatOpenAI, agent constructor helpers, and more than 30 additional optional packages? Or would you rather build directly against langchain-core and langgraph, skipping that extra surface area?
Either route still runs on LangGraph underneath. What differs is everything else that gets pulled into your environment alongside it.
If you're building a production agent image where you want a tightly scoped, easily auditable set of dependencies, installing langgraph plus whichever provider client you actually need gives you a leaner footprint. If you're prototyping quickly and want ChatOpenAI working without hand-rolling a provider wrapper, pip install langchain[openai] gets you there with less setup.
One detail worth calling out explicitly: langchain-core installs LangSmith, LangChain's tracing client, as a required dependency. It won't send any data unless you explicitly configure it to. But if you're reviewing exactly what ends up inside your container, it's there regardless of whether you ever turn it on.
Why the choice matters beyond installation size
A controlled comparison was run between LangGraph 1.2.9 and Pydantic AI 2.13.0 across four tasks, totaling 160 runs using gpt-4o. Both frameworks reached 100% correctness. LangGraph came in roughly 1.4 to 1.8 seconds faster in wall-clock time, a gap attributable to Pydantic AI's async-to-sync bridging, but accuracy was indistinguishable between the two.
What actually shifted outcomes was the underlying model, not the framework choice. Running the identical tasks with gpt-4o-mini instead produced a full failure — 0 out of 20 — on one task involving date arithmetic, an edge case that the larger model handled without trouble.
In short: deciding between LangChain and LangGraph mostly means deciding how much of the surrounding LangChain ecosystem you want pulled into your project, since both run on the same underlying engine. Deciding between LangGraph and Pydantic AI, on the other hand, means comparing two genuinely separate libraries — and the results above suggest that at gpt-4o, correctness doesn't favor either one, though the latency gap is real enough to be worth measuring in your own setup.