NR
>_

What I learned about LangGraph

🧠 My Journey Into State Machines for LLMs

Recently, I decided to dive into AI and LLMs. I had already built a few simple MCP servers using TypeScript,

Then I decided to dive LangChain and RAG system. I watched a few tutorials — most of them were Python-based and, unfortunately, a bit outdated.

When I tried to follow along, I noticed that some classes used in those videos were already deprecated. That’s when I stumbled upon LangGraph, which looked like an extension or evolution of LangChain.

At first, I was confused. I don’t have a formal background in AI — I didn’t study it in university. So I started self-learning and asking questions directly to an LLM (shoutout ChatGPT).


🤔 My First Impressions of LangGraph

Initially, I thought LangGraph was just a tool to give memory to an LLM. While working with LangChain, I noticed that many of the memory-related classes were replaced or deprecated in favor of LangGraph persistence — so I followed the examples blindly and ended up building a simple LangGraph-powered console chat app in TypeScript using Bun.

But every time I wanted to improve the app, I kept getting redirected back to LangGraph concepts. That’s when I realized: I need to actually understand what this thing is .


💡 What LangGraph Really Is (At Least To Me)

At its core, LangGraph is like a state management system — but designed to handle the complexity of LLM apps. You define:

  • Nodes (each does some processing)
  • Edges (control the flow)
  • And a shared state (accessible to all nodes) It reminds me a lot of XState, or even n8n, where you define visual workflows as a set of steps connected by logic.

🏭 A Mental Model That Helped Me

Imagine a whiteboard in a factory. The factory has several chains (pipelines). Each station reads from the whiteboard, processes something, and writes its result back. The whiteboard holds the shared state.

  • Each operator is like a node’s callback function.
  • Each station is a node.
  • The whiteboard is the LangGraph state object.
  • The workflow on the whiteboard (arrows, instructions) is the graph edges. Operators don’t talk directly to each other. They just read and write to shared memory — and follow the flowchart.

🧱 Everything Is a Runnable

One important thing I realized while learning LangChain and LangGraph is this:

Almost everything is a Runnable.

LLM wrappers, tools, chains, retrievers — they all inherit from a common Runnable class and expose a common interface:

.invoke(input)output.

This makes the whole system feel super modular and composable. You can plug things together just like Lego blocks — because they all follow the same shape.

So when we’re defining a LangGraph workflow, we’re not doing anything magical. We’re just defining a set of nodes, and each node is usually just a Runnable.

graph.addNode("summarizer", summarizerRunnable);
graph.addNode("qaTool", questionAnsweringRunnable);

Each of those nodes can invoke() on a piece of input — usually some shared state. That’s it!


🧠 LangGraph for Frontend Devs: Think of It Like Redux or Zustand

If you come from frontend dev (React/TS/etc), it might help to think of LangGraph like this:

  • The state in LangGraph is like your global app state.
  • Each node (Runnable) is like a reducer, selector or even a mutator function.
  • The edges between the nodes represent the explicit control flow , just like Xstate transition or middleware chaining.
  • Calling graph.compile() is like wiring up your state logic.

So in short:

LangGraph is a state manager with built-in control flow — like a programmable XState with LLM support.

LangGraph gives you a way to:

  • Manage shared memory/state
  • Pass that state between logic units (nodes)
  • Control the flow of execution (like a state machine)

So unlike Redux where reducers just fire based on actions, in LangGraph, you manually define the control flow — like:

START → nodeA → nodeB → nodeC → END

That’s the special twist: it’s a state manager with a built-in flow engine.


📦 Bonus: Runnables Are Both Mutators and Consumers

Runnables can:

  • Consume part of the state (like a selector)
  • Mutate or extend it (like a reducer)
const summarizer = Runnable.from(async (state) => {
  const summary = await someLLM.predict(state.inputText);
  return { ...state, summary };
});

So if you’re used to manipulating state in frontend apps — LangGraph won’t feel that foreign.


Now Let’s Look at a Simple Graph

const graph = new StateGraph(MessagesAnnotation);

Define nodes:

graph
  .addNode("firstNode", firstNodeRunnable)
  .addNode("secondNode", secondNodeRunnable)
  .addNode("thirdNode", thirdNodeRunnable);

This just drops 3 independent nodes into the space:

Now connect the dots (add edges):

graph
  .addEdge(START, "firstNode"); // start -> firstNode
  .addEdge("firstNode", "secondNode")// firstNode -> secondNode
  .addEdge("secondNode", "thirdNode")// seconNode -> thirdNode
  .addEdge("thirdNode", END); // thirdNode -> END

Resulting in this flow:

START → [firstNode] → [secondNode] → [thirdNode] → END

Now compile the graph:

const app = graph.compile();

~/ $ ls -la contacts/

CONNECT

© 2026 NURBXFIT [ system online ]