Migration
From LangGraph boilerplate to Nodex
Keep the graph model, remove repetitive wiring, and get a cleaner execution trace automatically. The two code blocks below show the same two-node graph written in raw LangGraph and in Nodex.
LangGraph (before)
from langgraph.graph import END, START, StateGraph
def research(state):
return {"notes": state["query"]}
def writer(state):
return {"final": state["notes"].upper()}
graph = StateGraph(dict)
graph.add_node("research", research)
graph.add_node("writer", writer)
graph.add_edge(START, "research")
graph.add_edge("research", "writer")
graph.add_edge("writer", END)
app = graph.compile()
app.invoke({"query": "LangGraph"})
Nodex (after)
from nodex import Agent
app = Agent()
@app.node(next="writer")
def research(state):
return {"notes": state.get("query")}
@app.node(next="end")
def writer(state):
return {"final": state.get("notes").upper()}
app.run({"query": "LangGraph"})
Removed ceremony
What you no longer need to write
Nodex handles this wiring internally. You can delete it from your existing agent code.
| StateGraph(dict) | Nodex creates the underlying LangGraph graph automatically when you call app.run(). |
|---|---|
| graph.add_node(name, fn) | Replaced by @app.node(). The function name becomes the node name. |
| graph.add_edge(A, B) | Replaced by next="node_name" on the decorator. |
| graph.add_edge(START, first) | Nodex infers the first node automatically from registration order. |
| graph.add_edge(last, END) | Replaced by next="end" on the last node. |
| graph.compile() | Called automatically inside app.run(). |
| Custom retry loops | Replaced by retry=N and on_fail="node_name" on @app.node(). |
Checklist
Migration checklist
| Nodes | Move each LangGraph node function under @app.node. |
|---|---|
| Edges | Replace direct edges with next="node_name". |
| END | Use next="end" for terminal nodes. |
| Conditional edges | Use @app.route(condition, if_true, if_false). |
| State reads | Replace state["key"] with state.get("key"). |
| Retries | Move retry logic from try/except wrappers to retry=N, on_fail= on the decorator. |
| Tests | Test one full graph path and key nodes in isolation with test_node(). |
Escape hatch
Still need raw LangGraph?
Nodex is a layer, not a lock-in. If you need advanced LangGraph features — subgraphs, streaming, checkpointers — you can still use them directly. Nodex compiles down to a standard LangGraph graph, so you can drop back to the LangGraph API for anything not covered by Nodex decorators.
The LangGraph documentation covers advanced features like streaming, persistence, and human-in-the-loop at the framework level.