Skip to main content
The JSX API is Smithers’ component-based authoring layer. You describe the workflow as a tree of <Workflow>, <Task>, and control-flow components, and Smithers renders that tree into an execution plan. You can mix normal <Task> nodes and MDX prompt components in the same JSX tree. Use JSX when you want:

What JSX Looks Like

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

const analysisSchema = z.object({
  summary: z.string(),
});

const { Workflow, smithers, outputs } = createSmithers({
  analysis: analysisSchema,
});

export default smithers((ctx) => (
  <Workflow name="analyze-repo">
    <Sequence>
      <Task id="analyze" output={outputs.analysis}>
        {{ summary: `Analyze ${ctx.input.repo}` }}
      </Task>
    </Sequence>
  </Workflow>
));
The outputs object returned by createSmithers maps each schema key to its Zod schema. Passing output={outputs.analysis} instead of a magic string gives you compile-time type checking — a typo like output={outputs.anaylsis} is a type error, not a runtime surprise.

How JSX Execution Works

The JSX API is render-driven:
  1. Smithers renders the workflow tree with the current ctx.
  2. It extracts executable task descriptors from the rendered tree.
  3. It runs the ready tasks and persists their outputs.
  4. It renders again with the updated outputs in ctx.
That means branching and task visibility are usually expressed with normal JSX conditions:
const analysis = ctx.outputMaybe(outputs.analysis, { nodeId: "analyze" });

return (
  <Workflow name="code-review">
    <Task id="analyze" output={outputs.analysis}>...</Task>
    {analysis ? (
      <Task id="fix" output={outputs.fix}>...</Task>
    ) : null}
  </Workflow>
);

Two Common JSX Styles

Schema-driven JSX

Use createSmithers(...) with Zod schemas and the returned outputs object. This is the fastest JSX path and the best default for new workflows. The output prop is type-checked against the registered schemas.

Manual JSX

Use smithers(db, build) with explicit Drizzle table objects when you want lower-level control over persistence. Both styles compile to the same JSX renderer and execution engine.

Why JSX Works Well

  • component composition keeps large workflows modular
  • normal JSX conditions make branching and gating easy to read
  • TypeScript and Zod keep workflow data explicit and type-checked
  • MDX prompts fit naturally into the same authoring model

Next Steps

  • JSX Installation — Set up Bun, TypeScript, and optional MDX prompts.
  • JSX Quickstart — Build a two-step workflow.
  • Execution Model — Understand the render and run loop behind JSX workflows.
  • Workflow State — Learn how ctx.outputMaybe(...) reads persisted task outputs.
  • Control Flow — Choose between branching, approvals, loops, and parallel paths.
  • Workflow — Start with the root component reference.