Skip to content
Riadh Mnasri
← Back to blog
3 min read

LangChain4j vs Spring AI: two ways to bring a LLM into a JVM

After integrating Spring AI into a Kotlin backend, the natural next step was comparing it with LangChain4j, the other JVM library that comes up constantly in discussions about AI on the Java and Kotlin side. Both do roughly the same thing: call a LLM, manage tools, structure output, but they start from two opposite points, and that starting point shows in every line of code.

Two philosophies, not two implementations of the same idea#

Spring AI starts from the framework: a ChatClient injects like any Spring bean, configuration flows through the usual Spring mechanisms (application.yml, auto-configuration), and the integration aims to disappear into the conventions already in place on a Spring Boot project. LangChain4j starts from the model: the library assumes no framework, it exposes its own abstractions (chains, agents, conversational memory) that can coexist with Spring, Quarkus, Micronaut, or no framework at all.

Spring AILangChain4j
Starting pointThe Spring frameworkThe model and its abstractions
Framework dependencyStrong, built for Spring BootNone, usable standalone
Configurationapplication.yml, Spring auto-configurationExplicit construction in code
Structured outputentity(), direct deserializationAI Services interfaces, generated dynamically
Adoption curve on an existing Spring projectLow, fits into existing conventionsMedium, introduces its own vocabulary

What that looks like in code#

The same need, scoring a mission offer against a stack, is written in LangChain4j as an annotated interface rather than an imperative call:

java
interface MissionScorer {
    @SystemMessage("Score an offer from 0 to 100 against the given stack.")
    @UserMessage("Stack: {{stack}}\n\nOffer: {{mission}}")
    ScoreResult score(@V("stack") String stack, @V("mission") String mission);
}
 
MissionScorer scorer = AiServices.create(MissionScorer.class, model);
ScoreResult result = scorer.score(stackSummary, missionDescription);

The MissionScorer interface has no hand-written implementation here: LangChain4j generates one dynamically from the annotations. It's elegant, and it pushes the prompt to the same first-class status as a method signature. It's also what, for a developer coming from a pure Spring world, takes real adjustment time: the behavior no longer lives in the method body, it lives in its annotations.

Where Spring AI wins: an existing Spring Boot project#

Tip

On an existing Spring Boot backend, with its auto-configuration, observability and established conventions, Spring AI has an advantage that isn't technical but organizational: it doesn't ask you to learn a new vocabulary, just a new kind of bean.

That was the case for the example built on MissionMatch: Spring AI slotted into an existing hexagonal architecture without redefining anything, because everything else in the project already spoke Spring.

Where LangChain4j wins: portability and agents#

LangChain4j takes the lead as soon as the project isn't a Spring project, or as soon as the need goes beyond a simple model call: orchestrating multiple tools, conversational memory, agents that chain several calls. Its abstractions are designed for those cases from the start, where Spring AI stays closer to a typed HTTP client than to an agent-orchestration framework.

Warning

Picking LangChain4j for its agent capabilities on a project that, in reality, only needs a simple model call imports complexity and a vocabulary that aren't justified. The question isn't "which one is more powerful", it's "what does this specific project actually need to do".

The deciding factor, in practice#

The choice doesn't come down to performance benchmarks, both call the same model behind a thin abstraction layer. It comes down to one question: is the project already structured around Spring, or does it need a library that assumes nothing about the rest of the stack? On an existing Spring Boot backend, Spring AI costs less to adopt. On a neutral project, or one that genuinely needs to orchestrate multiple tools and agents, LangChain4j offers a vocabulary already designed for that, which Spring AI isn't meant to cover on its own.