Build LangGraph agents like Next.js apps. Dawn is the TypeScript meta-framework for LangGraph — author AI agents and workflows as filesystem routes with route-local tools, generated types, durable threads, and an HMR dev server. Keep the runtime, drop the boilerplate.
- Kill the LangGraph boilerplate. Export one
agent({ model, systemPrompt })descriptor. Dawn discovers it, wires route-local tools into the generated graph, and emits alanggraph.jsonpackage ready for LangSmith. - Filesystem-routed agents. Filesystem routes under
src/app/— colocate state schemas, tools, middleware, and tests next to the route they belong to. No more ad-hoc folders. - A real local dev loop.
dawn devruns your routes locally with Agent Protocol thread endpoints: create a thread, then call/threads/:thread_id/runs/waitor/threads/:thread_id/runs/stream. Iterate in seconds, then verify the generated deployment artifact before shipping. - Typed end to end (TypeScript). Route params, state, and tool I/O are generated as TypeScript types.
dawn verifyis your pre-deploy gate. - Durable by default. Every Dawn app ships a working SQLite checkpointer and thread store — no setup. Threads survive a
dawn devrestart, and an agent that pauses for human input resumes exactly where it left off. LangGraph defines the checkpoint interface; Dawn ships the default implementation. - Test and evaluate before shipping.
@dawn-ai/testingprovides CI-safe agent harnesses and fixture replay.dawn evalruns co-located evals in replay mode by default, with--liveand--recordfor local real-model checks. - Sandbox when execution needs isolation. Add
sandboxtodawn.config.tsto route workspace filesystem and shell calls through a provider;@dawn-ai/sandboxincludes a Docker reference implementation. - Two ways to drive the model. A route exports one of
agent(LLM picks tools at runtime, can pause for a human),workflow(deterministic typed async function when you own the order),graph, orchain. Same routing, same types, same dev loop — you choose who's in charge.
Same LangGraph deployment shape, less code to author.
// graph.ts
import { StateGraph, MessagesAnnotation, START, END } from "@langchain/langgraph"
import { ToolNode } from "@langchain/langgraph/prebuilt"
import { ChatOpenAI } from "@langchain/openai"
import { tool } from "@langchain/core/tools"
import { z } from "zod"
const greet = tool(async ({ name }) => `Hello, ${name}!`, {
name: "greet",
description: "Greet a user by name.",
schema: z.object({ name: z.string() }),
})
const model = new ChatOpenAI({ model: "gpt-5-mini" }).bindTools([greet])
const tools = new ToolNode([greet])
async function callModel(state: typeof MessagesAnnotation.State) {
return { messages: [await model.invoke(state.messages)] }
}
function shouldContinue(state: typeof MessagesAnnotation.State) {
const last = state.messages.at(-1) as any
return last?.tool_calls?.length ? "tools" : END
}
export const graph = new StateGraph(MessagesAnnotation)
.addNode("agent", callModel)
.addNode("tools", tools)
.addEdge(START, "agent")
.addConditionalEdges("agent", shouldContinue, ["tools", END])
.addEdge("tools", "agent")
.compile()// langgraph.json
{
"dependencies": ["."],
"graphs": { "hello": "./graph.ts:graph" },
"node_version": "22",
"env": ".env"
}// src/app/research/index.ts
import { agent } from "@dawn-ai/sdk"
export default agent({
model: "gpt-5-mini",
description:
"A deep-research assistant: plans sub-questions, dispatches researchers, and writes a cited report.",
systemPrompt:
"You are a deep-research coordinator. Search the corpus, cite every claim, and write reports to the workspace.",
})// src/app/research/tools/searchCorpus.ts
export default async ({ query }: { readonly query: string }) => {
return [{ path: "corpus/agent-architectures.md", title: "Agent architectures" }]
}dawn build emits the langgraph.json for you.
- Create a new app.
pnpm create dawn-ai-app my-dawn-app
cd my-dawn-app
pnpm install- Validate the app and generate types in one call.
pnpm exec dawn verify- Run the scaffolded research route with JSON stdin.
Live agent runs require model credentials, such as OPENAI_API_KEY. For an offline path with recorded fixtures, run pnpm test and pnpm exec dawn eval in the scaffolded app.
echo '{"messages":[{"role":"user","content":"What are common agent architectures?"}]}' | pnpm exec dawn run /research- Optionally start the local runtime in one terminal and send the same route through the Agent Protocol from another terminal.
In one terminal:
pnpm exec dawn dev --port 3001In another terminal:
THREAD_ID=$(curl -s -X POST http://127.0.0.1:3001/threads -H 'content-type: application/json' -d '{}' | jq -r .thread_id)
curl -s -X POST http://127.0.0.1:3001/threads/$THREAD_ID/runs/wait \
-H 'content-type: application/json' \
-d '{"route":"/research#agent","input":{"messages":[{"role":"user","content":"What are common agent architectures?"}]}}' | jq .Use /threads/$THREAD_ID/runs/stream with the same body when you want SSE events instead of a blocking JSON response.
The default scaffold is the deep-research app at /research. For the smaller greeter scaffold, run pnpm create dawn-ai-app my-dawn-app -- --template basic; that optional template uses /hello/[tenant].
Dawn routes live under src/app and export one runtime entry. New agent routes should use the agent() descriptor from @dawn-ai/sdk; Dawn discovers the route, wires route-local tools into the generated graph, generates types, and produces a langgraph.json package for LangSmith.
import { agent } from "@dawn-ai/sdk"
export default agent({
model: "gpt-5-mini",
systemPrompt:
"You are a research coordinator. Search the local corpus, dispatch specialists when useful, and cite every claim.",
retry: { maxAttempts: 3, baseDelay: 250 },
})Add state.ts for a route state schema, tools/*.ts for route-local tools, middleware.ts for access control, and run.test.ts for colocated scenarios.
The built-in agent() route materializes to a LangChain chat model. Dawn infers providers for known model families; set provider explicitly to one of the supported built-in provider ids for aliases, ambiguous model names, local models, or provider-router model ids. Raw graph and chain routes can still instantiate any provider directly.
⭐ Star Dawn on GitHub · 📚 Read the docs · 💬 Ask in GitHub Discussions
Contributions welcome — see CONTRIBUTING.md. Repo layout and dev commands in CONTRIBUTORS.md. Security: SECURITY.md. Please follow the Code of Conduct.
MIT. See LICENSE.

