On September 25, 2026, both of the serious Java options for building AI applications shipped releases on the same day. Spring AI put out 2.1.0-M1, the first milestone of a new line. LangChain4j put out 1.20.1, a patch on top of its non-blocking 1.20.0 release.
If you are starting a Java project that talks to an LLM this quarter, that coincidence is good news. Both frameworks are real, both are moving fast, and both are past the "is this a toy?" stage. The question is no longer "which one is viable?" It is "which one fits the application you are actually building?"
I spent most of this year building a production-style AI agent in Spring AI and documenting it in a 13-part series, so I know one side of this comparison from the inside. I have not built a production system on LangChain4j, and this article says so up front. What I have done is read its release train closely, including the messy 1.19.1 incident that tells you a lot about how the project operates. Everything below is sourced from official release notes and documentation, linked inline.
The one-sentence versions
Before the details, the honest short answer:
- Spring AI is the right default if your application already lives in Spring Boot. It is not just "Spring-flavored", it assumes the Spring programming model: auto-configuration, starters, an advisor chain around every chat call, and properties files for model keys.
- LangChain4j is the right default if your application lives anywhere else, or if it is aggressively reactive. Quarkus, Vert.x, plain Java, Helidon: LangChain4j treats Spring Boot as one integration among several, not the center of the universe.
That framing survives every detail that follows. Now the details, because the details are where projects get surprised.
Release cadence and maturity
Both projects release fast, but their maturity stories are different in kind.
- Spring AI hit 2.0.0 GA on June 12, 2026, rebuilt on a Spring Boot 4 and Framework 7 baseline, then shipped 2.0.1 in August and the 2.1.0-M1 milestone on September 25. The 2.0 release deliberately narrowed the core: a well-defined set of chat model providers supported out of the box, with the OpenAI, Anthropic, and Google integrations moving onto the vendors' own SDKs, maintained in collaboration with the Spring AI team. That is a bet on depth over breadth.
- LangChain4j is on its 1.20.x line as of September 25, 2026, with a release roughly every two to four weeks going back over a year. It got to 1.0 much earlier than Spring AI got to 2.0, and the API has had more time to settle under real usage.
One incident on the LangChain4j side is worth knowing about, not as a knock but as a data point. Version 1.19.1 was published to Maven Central by mistake, cut from the main branch instead of the release branch, which means it contained everything in 1.20.0 plus extra commits. Maven Central is immutable, so the artifacts cannot be pulled. The project responded with an unusually clear warning table explaining exactly which version to use and why upgrading from 1.19.1 to 1.19.2 would silently remove functionality. Fast, transparent, and slightly chaotic: that is the release culture you are signing up for. Spring AI's cadence is slower and more corporate, milestones first, GA later, fewer surprises.
Architecture: advisor chain vs return-type polymorphism
This is the deepest difference, and it shows up in the code you write every day.
Spring AI 2.0 moved the tool loop into an advisor chain. Every request through ChatClient passes through an ordered chain of advisors, and the chain supports looping, meaning an advisor can re-enter the chain downstream. The tool-call round-trip is now a ToolCallingAdvisor that auto-registers itself, and the same mechanism drives structured-output retries and evaluation loops. If you have spent years with Spring's servlet filter chains or Spring Security's filter chain, this will feel like coming home. Cross-cutting AI concerns (logging, RAG context injection, guardrails, retries) compose the same way web concerns always did in Spring.
Spring AI 2.1.0-M1 pushes further with MessagePart: messages are now ordered lists of typed parts (TextPart, ReasoningPart, ToolCallPart, MediaPart), so reasoning blocks and provider-specific payloads like Anthropic's thinking signatures round-trip faithfully instead of being flattened into text. That is the kind of plumbing you do not appreciate until a model update breaks your conversation history.
LangChain4j 1.20 made the threading model the API. Its AI Services pick their execution mode by return type: declare a method returning String and you get blocking, return CompletableFuture and you get async, return Flow.Publisher and you get a reactive stream, return TokenStream and you get token-by-token streaming. Since 1.20.0, non-blocking reaches into tools, memory, guardrails, and the retrieval graph, with async defaults that differ deliberately from sync (tools run concurrently, execution errors fail the call, parse errors go back to the LLM for repair).
The philosophy difference is stark. Spring AI says "the pipeline is the abstraction, and we route your call through it." LangChain4j says "your method signature is the abstraction, and the framework adapts to it." Neither is wrong. But if your service runs on WebFlux or Vert.x, a framework that blocks a thread for the entire tool-memory-guardrail loop is actively fighting your stack, and LangChain4j's return-type approach is built precisely for that. This is not hypothetical: the 1.20 release was aimed squarely at Quarkus, Vert.x, and WebFlux teams who were choking event loops on blocking AI calls.
Where each one runs
- Spring AI: Spring Boot 4.0 or 4.1 today, moving to a 4.2 baseline in the 2.1 line. That is the whole story, and it is also the whole limitation. If you are on Spring Boot 3.x, the 2.0 line is not your upgrade path without a bigger migration.
-
LangChain4j: plain Java with zero framework, plus dedicated integrations for Spring Boot and Quarkus. The Quarkus integration is first-class, not an afterthought. Recent releases keep deepening the Java-ecosystem bridges: a
HibernateContentRetrieverthat turns HQL queries into RAG context, and skill loading from the classpath so agent skills ship inside ordinary JARs.
MCP and the agent story
Both frameworks treat the Model Context Protocol as core infrastructure now, and both support client and server roles.
- Spring AI ships MCP client and server support with declarative handlers covering the full protocol callback model: annotations for LLM sampling, elicitation, and capability-change notifications. On the agentic side, 2.0 introduced Agent Skills, a portable implementation of the agentskills.io specification, plus file, shell, web-fetch, and auto-memory utilities. The team has also said a dedicated Spring AI Agents project lands in November 2026 under Spring experimental.
-
LangChain4j went the annotations-with-parameters route: since 1.20.1,
@McpClientSuppliermethods can take supplier parameters, so you can construct per-request MCP clients instead of one shared client per application. That matters more than it sounds in multi-tenant systems, where different tenants may need different MCP servers or credentials. Its agent tutorials cover persistent, recoverable execution state, the piece that hurts first when a long-running agent survives a restart.
If your agents are multi-tenant, LangChain4j's per-request MCP suppliers are a real advantage today. If you want agent tooling that follows the Spring programming model you already trust, the November agents project is the thing to watch.
JSON handling, a small thing that bites
Both projects now run on Jackson 3, aligned with Spring Boot 4's own migration. The difference is opt-in versus default:
- Spring AI 2.0 moved to Jackson 3 as part of its baseline. It comes with the framework.
-
LangChain4j made it opt-in: add the
langchain4j-jackson3module and its JSON routing switches over, remove it and everything returns to Jackson 2. Nothing changes for anyone who does not opt in, and the new line gives you typed JSON read/write exceptions instead of wrapped generic ones.
If you are mixing Spring Boot 4 with LangChain4j, opt in. Carrying Jackson 2 and Jackson 3 in one classpath is exactly the kind of dependency archaeology you do not want to debug at 2 AM.
The decision matrix
Save this part. Here is how I would choose, given what each project has actually shipped:
- Your app is Spring Boot 4 already? Spring AI. The advisor chain, auto-configuration, and Spring-native observability mean less glue code, and the vendor-maintained OpenAI, Anthropic, and Google integrations mean new model features arrive faster than they used to.
- Your app is Quarkus, Vert.x, or Helidon? LangChain4j, and it is not close. The return-type execution model exists because of you.
-
Reactive, high-concurrency service doing many simultaneous LLM calls? LangChain4j's
CompletableFutureandFlow.Publishermodes with concurrent tool execution are designed for exactly this tail-latency problem. -
Multi-tenant agents with per-tenant MCP servers or credentials? LangChain4j's parameterized
@McpClientSupplierhandles this today. - Plain Java, no framework, maximum control? LangChain4j. It works with nothing but a dependency and a model key.
- You want the slowest-moving, most corporate-predictable API? Spring AI. Milestones, upgrade notes, and a Boot-versioned baseline give you a schedule you can plan around.
-
Tightly coupled to Hibernate and relational data for RAG? Both can do it, but LangChain4j's
HibernateContentRetrievermakes the relational-to-RAG path nearly free.
One more honest note for Spring shops: using LangChain4j inside a Spring Boot app is fully supported, and plenty of teams do it. The choice is not "Spring AI or exile." It is about which abstraction you want your AI code to speak.
What I would do differently if I started today
I built my agent on earlier Spring AI, before the 2.0 advisor-chain redesign. Knowing both release trains now, three things I would change:
-
Lean on
ChatClientand advisors from day one, notChatModelcalls with hand-rolled loops. Spring AI 2.0 explicitly framesChatClientas the user-facing API andChatModelas a low-level building block, and code written against the advisor chain survives the agentic features coming in November. -
Model conversations as parts early. The
MessagePartrework in 2.1.0-M1 is where the API is clearly heading, and code that assumed flat text will need touching as reasoning models spread. - Steal the return-type idea regardless of framework. Even in Spring AI, keeping the LLM boundary behind an interface whose return types express blocking versus streaming paid off more than any framework feature. The boundary is the architecture.
The bottom line
Both of these projects are good now. That is the headline that would have been hard to write a year ago, when neither had a stable 1.0 and every tutorial came with a "this API will change" warning. Two mature options, shipping within days of each other, each with a clear philosophy: Spring AI makes your AI code Spring code, LangChain4j makes your Java code AI-capable wherever that Java runs.
Pick by the stack your application already lives in, not by which release notes read better. The framework you choose is a ten-year conversation with your codebase; the model behind it changes every quarter.
I write about Java, Spring Boot, and AI every week. Subscribe, it is free.
So, which one is running in your project, and what pushed you that way? If you have hit the blocking-call problem on WebFlux or the multi-tenant MCP problem, I would genuinely like to hear how you solved it.
Top comments (0)