Skip to main content
Workflows are JSX trees. Smithers renders the tree, extracts ready tasks, executes them, persists their outputs, and re-renders. Branching, looping, and parallelism are normal JSX.

Setup

Most projects should use bunx smithers-orchestrator init — it scaffolds everything below. To embed into an existing codebase:
bun add smithers-orchestrator ai @ai-sdk/anthropic zod
bun add -d typescript @types/bun @types/ws
Minimal tsconfig.json:
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "jsxImportSource": "smithers-orchestrator",
    "strict": true,
    "noEmit": true,
    "skipLibCheck": true
  }
}
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

/** @jsxImportSource smithers-orchestrator */
import { createSmithers, Sequence, Task } from "smithers-orchestrator";
import { z } from "zod";

const { Workflow, smithers, outputs } = createSmithers({
  analysis: z.object({ summary: z.string() }),
});

export default smithers((ctx) => (
  <Workflow name="analyze">
    <Sequence>
      <Task id="analyze" output={outputs.analysis}>
        {{ summary: `Analyze ${ctx.input.repo}` }}
      </Task>
    </Sequence>
  </Workflow>
));
outputs.analysis is the typed reference for the Zod schema — typos are compile errors.

Reactivity

The tree re-renders on every frame, so branching is a normal JSX conditional:
const analysis = ctx.outputMaybe(outputs.analysis, { nodeId: "analyze" });
{analysis ? <Task id="report" output={outputs.report} agent={writer}>...</Task> : null}
The report Task doesn’t exist in the plan until analysis completes. No placeholder, no skipped node — the conditional IS the dependency.
  • 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.