LangGraph4j: stateful agent graphs for Java, and where the beta line bites
🚀 LangGraph for Java is a library for Graph Engineering, designed to build sophisticated AI agentic architectures within the Java ecosystem. It works seamlessly with both Langchain4j and Spring AI.
At a glance
- What is it?
- LangGraph4j is an MIT-licensed Java library for building stateful, cyclical agent graphs, with integrations for Langchain4j and Spring AI. This review covers the StateGraph model, the 1.9 beta versus 1.8 LTS split, and the checkpoint savers you must host yourself.
- Who is it for?
- Adopt LangGraph4j if you already run agents on the JVM and need explicit control flow, checkpoints and streaming rather than a framework that hides the loop. Stay away if you want a stable API today, because the 1.9 line the README points new users at is still labelled beta while 1.8.x sits on the support/1.8.x branch.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The JVM gap LangGraph4j fills
Python has had LangGraph for a while. Java teams that want the same execution model, a graph of nodes sharing mutable state with loops allowed, have had to hand-roll a scheduler and a state container, or bend a workflow engine into a shape it was not designed for. LangGraph4j is the attempt to close that gap without leaving the JVM. The README is explicit that it is inspired by LangGraph, part of the LangChain AI project, and that it is built to work with langchain4j and Spring AI.
The audience is narrower than the topic suggests. This is not a tool for calling an LLM once and printing the answer. It is for people who need control flow that can revisit a node: an agent that retries a failed tool call, a router that sends work back for clarification, a pipeline where one step decides whether another runs at all. The README frames the value as explicit control flow and cyclical graphs, in contrast to traditional DAGs. If your orchestration is genuinely a straight line, a graph library adds concepts without adding capability.
StateGraph, AgentState and reducers: the actual mechanism
The core class is StateGraph<S extends AgentState>. You add nodes and edges to it, and it is parameterized by an AgentState, which is essentially a Map<String, Object> passed from node to node. Nodes are functions or classes implementing NodeAction<S> or AsyncNodeAction<S>. Each one receives the current state and returns updates to it.
The part that decides whether the library feels natural or fights you is the schema. It is a Map<String, Channel.Reducer>, and every key in that map is an attribute of the state. A reducer defines how an update to an attribute is applied: a new value might overwrite the old one, or it might be appended to a list. Channel.Default<T> supplies a value when the attribute is not set. Channel.Appender<T> and MessageChannel.Appender<M> accumulate values, and the message variant also handles deletion by ID, which matters once you are trimming conversation history rather than only growing it.
That design is the whole architecture in miniature. Execution is a loop over nodes, state is a map, and the reducer is the contract that stops two nodes from clobbering each other's writes. It also means the interesting bugs are not in the graph topology but in the reducers: an attribute with an overwrite reducer that two branches both write will lose one of the writes, and nothing in the graph shape warns you.
Getting started: Maven coordinates and the sample environment
The README points at Maven Central for releases; the badge resolves to the org.bsc.langgraph4j group, and the core artifact is langgraph4j-core. The repository also ships a langgraph4j-bom module, which is the cleaner way to keep the core and any saver module on the same version.
Version selection is the first real decision. The newest published release in the repository's release list is v1.9.0-beta6, dated 2026-09-06, and the README states the repo has been updated to 1.9 while 1.8 moved to the branch support/1.8.x. If you want the LTS line instead, you resolve 1.8.27, the last non-beta release listed.
The Java baseline is the same for both lines: the README's release table gives Java 17+ for 1.9.x, for the 1.9-SNAPSHOT development builds, and for the 1.8.x LTS release. The development builds are flagged as pre-release; the README says snapshot users should expect active development and pre-release changes.
For a first run, the samples directory is the practical starting point, and the repository's .env.sample shows the two variables the samples expect:
OPENAI_API_KEY=
TAVILY_API_KEY=Those names are worth noticing. The sample environment assumes an OpenAI-backed model and Tavily for search, so the first thing you run will be a networked agent rather than a pure graph exercise. The README's own entry point for learning the execution model is the "Your First Graph - A Simple Example" section, which builds a linear flow with StateGraph, normal edges and shared state before introducing conditional edges. Its pattern matrix maps conditional routing to conditional edges, resumable flows to CheckpointSaver plus CompileConfig, and visual inspection to Studio.
Checkpoints are a feature and an operations bill
Checkpoints are described in the README as saving graph state at any point so you can replay or inspect it later, and they are the reason the repository has so many top-level modules. Alongside langgraph4j-core there are savers for Postgres, MySQL, SQLite, Redis, Oracle, DynamoDB, Hazelcast and CockroachDB, plus langgraph4j-opentelemetry for tracing.
That module list is the honest shape of the project. Persistence is not solved inside the library; it is delegated to a store you choose and then operate. Adopting LangGraph4j for a long-running workflow means adopting a database dependency at the same time, with the usual questions about schema migration, connection pooling and what happens when the store is unreachable mid-run. The README does not document rollback behaviour for a failed checkpoint write, and it does not describe a retention or compaction policy for stored checkpoints. If your state carries message history, that is data growth you own.
The upside is that the choice is yours. A team already running Postgres can keep checkpoints in the same database as the rest of its data instead of adding a service. A team that wants no external dependency can start with the in-process path and add a saver later, since the saver is supplied through CompileConfig rather than baked into the graph definition.
Where LangGraph4j is the wrong tool, and what to use instead
The clearest mismatch is a team that wants Spring AI to own the orchestration. Spring AI already provides its own abstractions for prompts, chat clients and tool calling, and LangGraph4j sits alongside that rather than replacing it. If your application is a request that calls a model and returns a response, adding a StateGraph means maintaining a schema, reducers and a compile step for a flow with no branches. The README's own pattern matrix reflects this: it recommends the graph path for linear flows as a learning exercise, not as the production default.
The second mismatch is API stability. The README directs new readers to 1.9 and describes that line as carrying new experimental features and improvements for preparing a move to 2.0. A team that cannot absorb pre-release changes should be on 1.8.x, which the README says will be maintained for LTS support with only bugfix or minor improvement. That is a real fork in the road, and it is not a decision the library can make for you.
For a genuine alternative, compare it with LangGraph in Python. They share the vocabulary, since LangGraph4j is inspired by it, but the difference is not just the language. Choosing Python means choosing that ecosystem's integrations and deployment story; choosing LangGraph4j means staying on the JVM with langchain4j or Spring AI and accepting that the Java port trails the original in features. The README's own framing of 1.9 as preparation for 2.0 suggests the port is still converging rather than finished. If your team is language-agnostic and wants the most complete implementation, the Python project is the safer bet. If your services, build and on-call rotation are Java, that is the trade LangGraph4j exists to make acceptable.
Maintenance, licensing and the cost of following 1.9
The repository is not archived, and the last push was on 2026-09-07, so this is a project with recent activity rather than a dormant one. The release cadence visible in the release list is fast: v1.9.0-beta6 on 2026-09-06, v1.9.0-beta5 the same day, and v1.8.27 on 2026-09-05. Frequent beta tags are a signal about process as much as about progress. It means fixes arrive quickly and it also means the version you pin can be superseded within days.
The licence is MIT, which is permissive and places few obligations on how you redistribute the library. That is the extent of what can be said here; the repository's LICENSE file is the authoritative text, and questions about your own distribution or patent posture belong with your legal counsel rather than with a review.
The upgrade cost is concentrated in one place. Staying on 1.8.x means a slower-moving branch and a smaller feature surface. Moving to 1.9 means tracking experimental features whose shape the README ties to an eventual 2.0. Either way, the checkpoint savers are separate artifacts, so a version bump is not a single-line change: the core, the BOM and whichever saver module you use all need to move together, and the store schema behind that saver is your migration to plan.
Editorial conclusion
Adopt LangGraph4j if you already run agents on the JVM and need explicit control flow, checkpoints and streaming rather than a framework that hides the loop. Stay away if you want a stable API today, because the 1.9 line the README points new users at is still labelled beta while 1.8.x sits on the support/1.8.x branch. Before committing, verify which line your build resolves, whether you can operate the checkpoint store you pick, and whether the Studio UI is a requirement, since it is a separate module rather than part of the core artifact.
Frequently asked questions
What are the differences between LangGraph4j and LangGraph?
LangGraph4j is a Java library inspired by LangGraph, which is part of the LangChain AI project. The README describes it as built for the Java ecosystem and designed to work with langchain4j and Spring AI, so the main difference is the runtime and the integrations rather than the graph model itself.
What is lang4j?
That term is not defined by the project. The library described here is LangGraph4j, a Java library for building stateful, multi-agent applications with LLMs, inspired by LangGraph and built for work with langchain4j and Spring AI.
Can LangGraph be used in Java?
Yes. LangGraph4j is a Java library for building stateful, multi-agent applications with LLMs, and the README states the release table requires Java 17+ for both the 1.9.x and 1.8.x lines.
What is langgraph4j?
It is a Java library for graph engineering in agentic AI workflows, letting you define cyclical graphs where nodes share state through an AgentState map. The README describes it as inspired by LangGraph and built for work with langchain4j and Spring AI.
langgraph4j vs langgraph python
LangGraph4j is inspired by LangGraph, part of the LangChain AI project, and keeps the same graph vocabulary while running on the JVM with langchain4j or Spring AI. The README ties the 1.9 line to experimental features preparing a move to 2.0, which suggests the Java port is still converging on the Python original.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/langgraph4j-langgraph4j)