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 when | Use Substructure when |
|---|---|
| The control flow is novel | The agent is a teammate, not a graph |
| You want the LangChain ecosystem | You want Slack, MCP auth, and history already built |
| Your team is Python or TypeScript | Your 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-adapterswith 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
| LangGraph | Substructure | |
|---|---|---|
| The agent is | A compiled graph in your process | A file in your repo |
| Language | Python or TypeScript | Any language, over HTTP |
| Loop control | Full, in your own code | Full, over the wire |
| Subagents | Subgraphs you wire | One config line |
| People in the loop | interrupt(); the surface is yours | Approval in Slack |
Running it
| LangGraph | Substructure | |
|---|---|---|
| State | Checkpoints at superstep boundaries | An event log per session |
| Crash mid-node | That node's work is lost | The step resumes |
| After a crash | The node runs again from its start | The engine continues where it stopped |
| You operate | Postgres and the service around it | Nothing, or one binary |
Surfaces and price
| LangGraph | Substructure | |
|---|---|---|
| Slack | Fleet, or your own gateway | One command |
| MCP auth | Yours | The engine's |
| Browser clients | An AG-UI adapter | AG-UI, native |
| Self-host | MIT core; the platform needs a licence | The full product |
| Price | Seats plus metered compute | Flat, 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.