Substructure vs. LangGraph for AI agents

Checked August 7, 2026

LangGraph is for teams whose control flow is the product: a graph of your own functions over typed state, in your own process. Substructure is for teams who want the agent itself: config in git, running in Slack, with every step of the loop open to your code.

Use LangGraph whenUse Substructure when
The control flow is novelThe agent is a teammate, not a graph
You want the LangChain ecosystemYou want Slack, MCP auth, and history already built
Your team is Python or TypeScriptYour code is Go, Ruby, or anything on HTTP

What Substructure does that LangGraph does not

  • Answers in Slack from the config file. LangGraph: build the gateway yourself, or use Fleet, the no-code layer.
  • Restarts a dead run by itself. LangGraph: nothing in the open-source package notices a dead process. Automatic resumption is in the paid Agent Server.
  • Holds the MCP credentials. LangGraph: langchain-mcp-adapters with do-it-yourself auth; managed auth is in the paid platform.
  • Runs your code in any language. LangGraph: Python or TypeScript, in process.
  • Stores sessions itself. LangGraph: you supply Postgres and prune the checkpoints.

Side by side

Building the agent

LangGraphSubstructure
The agent isA compiled graph in your processA file in your repo
LanguagePython or TypeScriptAny language, over HTTP
Loop controlFull, in your own codeFull, over the wire
SubagentsSubgraphs you wireOne config line
People in the loopinterrupt(); the surface is yoursApproval in Slack

Running it

LangGraphSubstructure
StateCheckpoints at superstep boundariesAn event log per session
Crash mid-nodeThat node's work is lostThe step resumes
After a crashThe node runs again from its startThe engine continues where it stopped
You operatePostgres and the service around itNothing, or one binary

Surfaces and price

LangGraphSubstructure
SlackFleet, or your own gatewayOne command
MCP authYoursThe engine's
Browser clientsAn AG-UI adapterAG-UI, native
Self-hostMIT core; the platform needs a licenceThe full product
PriceSeats plus metered computeFlat, bring your own key

What you write

agent.py
graph = StateGraph(State)
graph.add_node("agent", call_model)
graph.add_node("tools", ToolNode(tools))
graph.add_conditional_edges("agent", should_continue)
graph.add_edge("tools", "agent")
app = graph.compile(checkpointer=PostgresSaver(pool))
subs.toml
[agent.oncall]
llm = "openrouter"
model = "moonshotai/kimi-k3"
system = "You are the on-call assistant."
mcp = [{ id = "sentry", tools = { read_only = true } }]

[agent.oncall.slack]
name = "Oncall"

Add a worker URL to that file and the engine sends every decision to your endpoint as JSON, one step at a time.

Where LangGraph is the better choice

  • Novel control flow, expressed in your own process.
  • Typed state, dynamic graphs, and time travel from any checkpoint.
  • The LangChain integrations and LangSmith observability.
  • A very large community, so most problems already have an answer.

Questions

Can I keep my own agent logic? Yes. Every prompt, model call, and tool run arrives at your worker as JSON, to accept or replace.

Do I have to run a database? No. Self-hosted, the engine's store is one SQLite file.

Can I use both? Yes. A worker can call a graph you already have.

The quick start takes about five minutes.