LangGraph for Java. A library for develop AI Agentic Architectures in the Java ecosystem. Designed to work seamlessly with both Langchain4j and Spring AI.
LangGraph for Java. A library for develop AI Agentic Architectures in the Java ecosystem. Designed to work seamlessly with both Langchain4j and Spring AI.
[][documentation] [][snapshots] [][releases]
LangGraph for Java. A library for building stateful, multi-agents applications with LLMs, built for work with [langchain4j] and [Spring AI]
It is inspired by [LangGraph] solution, part of [LangChain AI project].
‼️ the repo has been updated to 1.9, the version 1.8 has been moved to the branch support/1.8.x..
Take a look to What's new in release 1.9
| Date | Release | info |
|---|---|---|
| Sep 12, 2026 | 1.9.0-beta7 |
last release |
| Release line | Java baseline | Notes |
|---|---|---|
| 1.9.x | Java 17+ | Release with new (experimental) features and improvements for preparing move to 2.0 |
1.9-SNAPSHOT development builds |
Java 17+ | Snapshot users should expect active development and pre-release changes |
1.8.x LTS release |
Java 17+ | This relase will be maintained for LTS support in branch support/1.8.x. Only bugfix and/or minor improvement |
Welcome to LangGraph4j! This guide will help you understand the core concepts of LangGraph4j, install it, and build your first application.
LangGraph4j is a Java library for building stateful, multi-agent applications with Large Language Models (LLMs). It is inspired by the Python library LangGraph and is designed to work seamlessly with popular Java LLM frameworks like Langchain4j and Spring AI.
At its core, LangGraph4j allows you to define cyclical graphs where different components (agents, tools, or custom logic) can interact in a stateful manner. This is crucial for building complex applications that require memory, context, and the ability for different "agents" to collaborate or hand off tasks.
LangGraph4j offers several features and benefits:
| Pattern | Best for | Main abstraction | Start here |
|---|---|---|---|
| First graph / linear flow | Learning the core execution model | StateGraph, normal edges, shared state |
## Your First Graph - A Simple Example |
| Conditional routing | Router-style decisions and dynamic control flow | Conditional edges | ### Edges |
| Stateful checkpointed flow | Long-running or resumable workflows | CheckpointSaver, CompileConfig |
### Checkpoints (Persistence) |
| Framework-integrated agents | Using LangGraph4j with Java AI frameworks | LangChain4j / Spring AI integrations | ## BONUS: built-in integrations |
| Visual debugging and inspection | Observing and iterating on graphs interactively | Studio | ## Studio - Running Your Graph visually |
Understanding these concepts is key to using LangGraph4j effectively:
StateGraph<S extends AgentState>The StateGraph is the primary class you'll use to define the structure of your application. It's where you add nodes and edges to create your graph. It is parameterized by an AgentState.
AgentStateThe AgentState (or a class extending it) represents the shared state of your graph. It's essentially a map (Map<String, Object>) that gets passed from node to node. Each node can read from this state and return updates to it.
Map<String, Channel.Reducer>. Each key in the map corresponds to an attribute in the state.Channel.Reducer: A reducer defines how updates to a state attribute are handled. For example, a new value might overwrite the old one, or it might be added to a list of existing values.Channel.Default<T>: Provides a default value for a state attribute if it's not already set.Channel.Appender<T> / MessageChannel.Appender<M>: A common type of reducer that appends the new value to a list associated with the state attribute. This is useful for accumulating messages, tool calls, or other sequences of data. MessageChannel.Appender is specifically designed for chat messages and can also handle message deletion by ID.NodesNodes are the building blocks of your graph that perform actions. A node is typically a function (or a class implementing NodeAction<S> or AsyncNodeAction<S>) that:
AgentState as input.Map<String, Object> representing updates to the state. These updates are then applied to the AgentState according to the schema's reducers.Nodes can be synchronous or asynchronous (CompletableFuture).
EdgesEdges define the flow of control between nodes.
addEdge(sourceNodeName, destinationNodeName).AgentState. After a source node completes, an EdgeAction<S> (or AsyncEdgeAction<S>) function is executed. This function receives the current state and returns the name of the next node to execute. This allows for branching logic (e.g., if an agent decided to use a tool, go to the "execute_tool" node; otherwise, go to the "respond_to_user" node). Conditional edges are defined with addConditionalEdges(...).addConditionalEntryPoint(...).CompilationOnce you've defined all your nodes and edges in a StateGraph, you compile() it into a CompiledGraph<S extends AgentState>. This compiled graph is an immutable, runnable representation of your logic. Compilation validates the graph structure (e.g., checks for orphaned nodes).
Checkpoints (Persistence)LangGraph4j allows you to save (Checkpoint) the state of your graph at any step. This is extremely useful for:
CheckpointSaver implementation (e.g., MemorySaver for in-memory storage, or you can implement your own for persistent storage).Useful starting points for persistence:
langgraph4j-mysql-saver/README.md for MySQL-backed checkpointslanggraph4j-postgres-saver/README.md for PostgreSQL-backed checkpointslanggraph4j-redis-saver/README.md for Redis-backed checkpointsIf you only want to see the minimal integration point first, look for CompileConfig.builder().checkpointSaver(...) in the saver module examples before diving into the full storage details.
…To use LangGraph4j in your project, you need to add it as a dependency.
Maven:
Make sure you are using Java 17 or later.
Latest Stable Version (Recommended):
<properties>
<langgraph4j.version>1.8.13</langgraph4j.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.bsc.langgraph4j</groupId>
<artifactId>langgraph4j-bom</artifactId>
<version>${langgraph4j.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.bsc.langgraph4j</groupId>
<artifactId>langgraph4j-core</artifactId>
</dependency>
</dependencies>(Note: Always check the Maven Central Repository for the latest version number.)
Development Snapshot Version: If you want to use the latest unreleased features, you can use a snapshot version.
<dependency>
<groupId>org.bsc.langgraph4j</groupId>
<artifactId>langgraph4j-core</artifactId>
<version>1.8.13</version>
</dependency>You might need to configure your settings.xml or pom.xml to include the Sonatype OSS snapshots repository:
<repositories>
<repository>
<id>sonatype-oss-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>Let's create a very simple graph that has two nodes: greeter and responder.
The greeter node will add a greeting message to the state.
The responder node will add a response message based on the greeting.
Before you start, the shortest path is:
langgraph4j-core to your project.StateGraph + shared-state flow.1. Define the State: Our state will hold a list of messages.
…2. Define the Nodes:
…3. Define and Compile the Graph:
…Explanation:
SimpleState with a MESSAGES_KEY that uses AppenderChannel to accumulate strings.GreeterNode adds a "Hello" message.ResponderNode checks for the greeting and adds an acknowledgment.StateGraph is defined, nodes are added, and edges specify the flow: START -> greeter -> responder -> END.stateGraph.compile() creates the runnable CompiledGraph.compiledGraph.stream(initialState) executes the graph. We iterate through the stream to get the final state. EachNo open issues yet, or sync has not completed.