Mental Model

Dawn is a meta-framework for LangGraph.

Not because LangGraph is missing anything. It runs the graph well. Not because we needed another framework. We did not.

It exists because every team building agents on LangGraph ends up writing the same conventions by hand: project structure, type wiring, dev tooling, deployment scripts. We watched it happen at every company.

Dawn writes those conventions once. You write the agent.

tl;dr

  • A route is a folder. Its path is the agent endpoint.
  • A route's index.ts exports one of: agent, workflow, graph, chain.
  • Tools live next to routes. Their parameter types are inferred at build time.
  • State is the JSON payload passed through the route runtime.
  • Agent routes can opt into built-in behavior such as memory, planning, skills, subagents, and reasoning effort.
  • Middleware is an optional app-level request gate for the local Dawn runtime.
  • LangGraph runs the graph. Dawn does everything else.

The pieces

A route is a folder under src/app/. The folder path becomes the agent endpoint at runtime — src/app/(public)/hello/[tenant]/ answers to /hello/[tenant]. Everything a route needs lives next to it.

A route entry is the route's default behavior. Each route has exactly one index.ts that exports an agent, a workflow, a graph, or a chain. Pick the shape that fits the problem; mix shapes across routes in the same project.

Tools are TypeScript files in a route's tools/ directory. Each tool is a default-exported async function. Dawn reads each tool's parameter type at build time and turns it into a JSON schema. Agents call tools by name; the model picks when.

State is an optional typed shape declared in state.ts next to the route. Dynamic segments — [tenant], [...rest] — are preserved in the route id and generated route metadata; callers pass the corresponding values in the JSON input they send to the runtime.

Agent route features are discovered from files and descriptors. workspace/AGENTS.md provides memory, plan.md provides planning, skills/<name>/SKILL.md provides route-local skills, subagents/ provides child specialists, and reasoning tunes OpenAI-backed agent routes.

Middleware runs before route execution in the local Dawn runtime. It lives at src/middleware.ts (or root middleware.ts) and can reject a request or attach request-scoped context for tools.

The runtime

A typical request through Dawn looks like this:

text
$ echo '{"tenant":"acme"}' | dawn run "/hello/[tenant]"


   route id match    →   src/app/(public)/hello/[tenant]/index.ts


   input state       →   { tenant: "acme" }


   middleware        →   src/middleware.ts (auth, request context, ...)


   route entry       →   index.ts (agent | workflow | graph | chain)


   tool calls        →   ctx.tools.greet({ tenant })


   typed output      →   { greeting: "Hello, acme!" }

Each arrow is real code:

  1. Route id match. Dawn resolves the parameterized route id against the discovered file tree. Route groups ((public)/) drop from the path, so src/app/(public)/hello/[tenant]/index.ts becomes /hello/[tenant].
  2. Input state. The JSON input is passed to the route. Agent routes may apply defaults from state.ts; workflow, graph, and chain routes receive the runtime input for their adapter.
  3. Middleware. The app-level middleware runs when present. It can short-circuit the request or pass through with request-scoped context for tools.
  4. Route entry. The exported agent, workflow, graph, or chain runs. Dawn provides the typed RuntimeContext with the route's discovered tools.
  5. Tool calls. Tools called via ctx.tools.<name> are typechecked against the schemas Dawn generated at build time.
  6. Typed output. The route returns a typed value. Dawn streams or returns it depending on the call (dawn run, /runs/wait, /runs/stream).

Build vs runtime

Dawn does most of its work at build time.

dawn build and dawn typegen walk your routes, infer tool parameter types from function signatures, and emit .dawn/dawn.generated.d.ts. That generated file is the route registry, the tool registry, and the typed RouteTools<P> map. After build, your editor can autocomplete ctx.tools.greet and complain when a tool's signature drifts from its caller.

At runtime, dawn run and dawn dev execute. There is no manual tools: [...] array and no per-route registration. The build-time types and runtime dispatcher are wired up by Dawn — you write the agent.

Where Dawn ends and LangGraph begins

The boundary is sharp. Dawn does not replace LangGraph. It surrounds it.

Dawn ownsLangGraph owns
File-system routingThe graph runtime
Type inference for tools and stateStateGraph, channels
Dev server with HMRPersistence and resume
The CLI (dawn dev, dawn run)LangSmith deploy
Generated .dawn/dawn.generated.d.tsLangSmith integration

Dawn deletes the boilerplate. Not your stack.

You bring your own LangGraph workflows, your own LCEL chains, your own model providers, your own LangSmith tracing. Dawn does not change any of those. It puts conventions around them so the rest of your codebase stops being plumbing.

What to read next

Pick the path that fits where you are.

  1. I want to build something now.Getting Started
  2. I want to understand a piece in depth.Routes, Agents, Tools, State, Memory, Planning, Skills, Subagents, Reasoning Effort, Middleware, Retry
  3. I want to see the surface.CLI, Dev Server, Deployment

Related