LangChain.js: Building LLM Applications with TypeScript

Lesson 5 of 6

LangGraph.js: Stateful, Multi-Step Workflows

Just like its Python counterpart, LangGraph.js models a workflow as an explicit graph of typed state, nodes, and edges, instead of an implicit "loop until done." It's the tool to reach for once AgentExecutor's simple loop isn't enough, when you need branches, loops back to an earlier step, or several cooperating steps.

Defining typed state

TypeScript

Annotation.Root defines the shape of the state every node reads and updates, typed just like any other TypeScript object, at any point in the graph's execution, the current state is a plain, inspectable, fully-typed value.

Defining nodes

TypeScript

Each node is a plain async function that receives the current state and returns a partial object of updates to merge in, a real searchNode would call a search tool and answerNode would run an LCEL chain, kept as placeholders here since both need real API access.

Wiring the graph

TypeScript

addEdge('search', 'answer') is a fixed transition, addEdge('answer', END) marks answer as terminal, END is a special constant meaning "the graph is finished here."

Conditional edges

TypeScript

addConditionalEdges routes to a different next node based on a function of the current state, here looping back to search if results still look too thin, this explicit, typed branching is what a plain AgentExecutor loop doesn't give you directly.

TIP

The return type 'search' | 'answer' on needsMoreResearch is doing real work: TypeScript checks that the routing function can only return names of nodes that actually exist in the graph.

📝 LangGraph.js Quiz

Passing score: 70%
  1. 1.What does Annotation.Root define in LangGraph.js?

  2. 2.addConditionalEdges lets a graph route to a different next node depending on the current state, unlike a fixed addEdge.

  3. 3.In LangGraph.js, ____ is the special constant marking a node as the terminal step of the graph.