The model is “plan mode as code”: you define the plan as a JSX tree. Each <Task> is a node in a DAG; control flow is a small set of primitives (<Sequence>, <Parallel>, <Branch>, <Ralph>, <Task>).
After each task completes, Smithers validates the output (Zod) and persists it to SQLite, then re-renders the plan with updated context. If the process crashes, it resumes from the last completed node — no duplicated work, no lost state.
A quick “hear me out” on React: I tried a bunch of workflow APIs (builder patterns, Python DSLs, Starlark/Bazel-ish rules, even Solid). The thing React gives me that none of those did as cleanly is this: re-rendering is planning. Every step updates durable state, then the “plan function” runs again and produces the next DAG. On top of that you get very readable composition: small reusable workflow components, normal conditionals, and a familiar mental model for evolving systems.
The part that’s been most useful in practice: I write Smithers scripts with AI, and then have AI monitor runs and iterate on the workflow while it executes (fix prompt/schema/logic issues, adjust steps, improve components). Because state is durable and the plan is declarative, the workflow can evolve without throwing away progress.
What I’d love feedback on is usability:
- Would you use this? For what kinds of workflows?
- Does the API feel natural (Task IDs, context access, retries/loops, composition)?
- What observability would you expect (why a node ran, plan diffs between renders, traces, run UI/CLI)?
<Ralph until={ctx.latest("review","r")?.approved} maxIterations={3}>
</Ralph>The model is “plan mode as code”: you define the plan as a JSX tree. Each <Task> is a node in a DAG; control flow is a small set of primitives (<Sequence>, <Parallel>, <Branch>, <Ralph>, <Task>).
After each task completes, Smithers validates the output (Zod) and persists it to SQLite, then re-renders the plan with updated context. If the process crashes, it resumes from the last completed node — no duplicated work, no lost state.
A quick “hear me out” on React: I tried a bunch of workflow APIs (builder patterns, Python DSLs, Starlark/Bazel-ish rules, even Solid). The thing React gives me that none of those did as cleanly is this: re-rendering is planning. Every step updates durable state, then the “plan function” runs again and produces the next DAG. On top of that you get very readable composition: small reusable workflow components, normal conditionals, and a familiar mental model for evolving systems.
The part that’s been most useful in practice: I write Smithers scripts with AI, and then have AI monitor runs and iterate on the workflow while it executes (fix prompt/schema/logic issues, adjust steps, improve components). Because state is durable and the plan is declarative, the workflow can evolve without throwing away progress.
What I’d love feedback on is usability:
- Would you use this? For what kinds of workflows?
- Does the API feel natural (Task IDs, context access, retries/loops, composition)?
- What observability would you expect (why a node ran, plan diffs between renders, traces, run UI/CLI)?
- What’s missing for real-world runs (cancellation, rate limits, caching, backpressure, concurrency controls)?
Repo: https://github.com/evmts/smithers
Article I wrote: https://x.com/FUCORY/status/2021442919299940381