Setup
Most projects should usebunx smithers-orchestrator init; it scaffolds everything below.
To embed into an existing codebase:
tsconfig.json:
jsxImportSource is the only non-standard line; it routes JSX through smithers-orchestrator/jsx-runtime instead of React DOM.
Optional MDX prompts: add bun add -d @types/mdx and a preload.ts that calls mdxPlugin(), register it in bunfig.toml as preload = ["./preload.ts"].
Verify with bunx tsc --noEmit and bunx smithers-orchestrator --help.
A minimal workflow
outputs.analysis is the typed reference for the Zod schema, so typos are compile errors. The task body is a JSX expression ({...}) whose value is a plain object, with no LLM call here, just a static return. Real tasks pass a run prop or an AI model. See the Task component reference.
Reactivity
The tree re-renders on every frame, so branching is a normal JSX conditional. Inside a workflow function,ctx exposes ctx.input and ctx.outputMaybe(ref, { nodeId }). The latter returns the output of a completed task, or undefined if it hasn’t run yet:
report Task doesn’t exist in the plan until analysis completes. No placeholder, no skipped node. The conditional IS the dependency. Unlike static DAG tools that require you to declare optional nodes upfront, the JSX conditional is evaluated fresh each frame: if analysis is undefined, the report task simply doesn’t exist in that frame’s plan.
Read next
- Tour: six-step worked example with agents, schemas, approvals, resume.
- How It Works: the render → execute → persist loop.
- Components: full prop surface for every JSX element.