Skip to content
motif-ts

Workflow Orchestration
Reimagined

Dead simple. Fully typed. Agentically orchestrated.

@motif-ts/agentic
Describe your workflow...

The whole loop, end to end: an agent turns intent into a canonical workflow spec, asks when it needs a decision, then runs the compiled graph with schema validation and an observable execution lifecycle. Hover to pause; pick a scenario below.

Design Principles

Six commitments that make workflows safe for humans to maintain — and for agents to operate.

Workflows as Graphs

Logic is explicit steps and edges, not hidden control flow. Every transition is deterministic and type-checked, so complex flows stay understandable, testable, and safe for an agent to reason about.

Type-Safety End-to-End

Zod schemas validate inputs, outputs, configs, and API calls at runtime; TypeScript infers everything statically. The same schemas that protect your code become the contract an LLM plans against.

Powered by
Zod

Immutability

State updates are immutable by default, so every change is predictable and replayable — the foundation for time-travel debugging, snapshots, and safe rewind-and-retry recovery.

Powered by
Zustand

Co-location

Each step owns its schemas, state, and API in one place — business rules live inside the step, not scattered across UI handlers. Steps stay pure, portable, and testable in isolation.

Framework Agnostic

The engine has zero UI or AI-SDK dependencies. It runs anywhere JavaScript runs; thin adapters bind it to React, Vue, or Svelte, and a callback binds it to whichever model provider you choose.

Agent Native

You own the LLM calls — motif-ts never talks to a model. Instead it hands your agent a precise, typed surface: describe the workflow, list invokable actions, emit tool catalogs, and drive a budgeted, approval-aware loop.

The Step Model

One primitive underneath everything: encapsulated logic with strict, schema-checked IO and reactive private state.

Step Context

Explore the anatomy of a step

Hover or tap any part of the diagram — or any highlighted token in the code — to see how each piece maps to a runtime schema and its inferred TypeScript type.

MyStep.ts
// 1. Define Step
const MyStep = step({
kind: 'my-step',
: z.object(...),
: z.object(...),
: z.object(...),
: z.object(...),
: myStepStore,
}, (args) => {
const { , , } = args;
const { , , , } = args;
(() => { ... });
return {
}
};
});
// 2. Register and start
const instance = MyStep;
const flow = workflow([MyStep])
.register([instance]);
flow.start({ id: 'job-1' });

Shape the Workflow

Loops, scopes, and nesting — three composition patterns that grow a graph without changing how any single step behaves.

Init
template
Process
Validate
iter ~1
Process
Validate
iter ~2
Process
Validate
until done
Done

Workflow Shape · 01

RepeatGroup

Make a fresh lane for each iteration.

Expands a declared template into a single linear sequence of new step instances. Input and ID validation finishes before a new lane is committed. History spans the lanes; edge direction still controls back-navigation.

RepeatGroup.ts
import { RepeatGroup, step, workflow } from '@motif-ts/core';
import { z } from 'zod';

const count = z.object({ count: z.number() });
const Init = step({ kind: 'Init', outputSchema: count }, ({ next }) => ({
  advance: () => next({ count: 0 }),
}));
const Process = step({ kind: 'Process', inputSchema: count, outputSchema: count },
  ({ input, next }) => ({ advance: () => next({ count: input.count + 1 }) }));
const Validate = step({ kind: 'Validate', inputSchema: count, outputSchema: count },
  ({ input, next }) => ({ advance: () => next(input) }));
const Done = step({ kind: 'Done', inputSchema: count, outputSchema: count },
  ({ input, next }) => ({ advance: () => next(input) }));

const RetryUntilDone = RepeatGroup({
  kind: 'RetryUntilDone', outputSchema: count,
  until: 'output.count >= 3', maxIterations: 5,
});
const init = Init('init'), process = Process('process');
const validate = Validate('validate'), done = Done('done');
export const flow = workflow([Init, Process, Validate, Done, RetryUntilDone])
  .register([init, process, validate, done])
  .connect(init, RetryUntilDone((g) => g.connect(process, validate)))
  .connect(validate, done);

flow.start(init); // Group attachment uses an explicit root for type inference.
// Each unsuccessful pass creates fresh template instances.
// Next-lane input and generated IDs are validated before graph mutation.
// 'until' reads { output, iteration }; edge 'when' reads output directly.

Edit the Spec. Run the Graph.

This playground runs the real engine in your browser: edit the canonical workflow spec on the left, watch the generated code update, then run it and drive every step by hand.

Workflow

Editing

6 steps, 5 edges

Tip: graph editing works best with a mouse or trackpad
WorkflowSpec
6 steps5 edges1 groups
No selectionSelect a step, group, or edge to inspect.
Your Code
import { RepeatGroup, workflow } from '@motif-ts/core'; import { InputStep, VerifyStep, PollStep, ProfileStep, PlanStep, SuccessStep } from './steps'; const input = InputStep("input"); const verify = VerifyStep("verify"); const poll = PollStep("poll"); const profile = ProfileStep("profile"); const plan = PlanStep("plan"); const success = SuccessStep("success"); const PollUntilReadyGroup = RepeatGroup({ kind: "PollUntilReady", until: 'output.ready === true', }); const flow = workflow([InputStep, VerifyStep, PollStep, ProfileStep, PlanStep, SuccessStep, PollUntilReadyGroup]); flow .register([input, verify, poll, profile, plan, success]) .connect(input, PollUntilReadyGroup((start) => start.connect(verify).connect(poll))) .connect(poll, profile) .connect(profile, plan) .connect(plan, success) .start(input);

One Stack, Layered

Core executes the graph. Agentic adds agent interactions and host run controls. Spec and Runtime provide canonical workflow data, trusted execution, and durability. Add middleware, tooling, and UI adapters as needed.

Workflow Engine

The in-memory workflow engine: typed steps and edges, lifecycle control, graph validation, and state observation. Repeat groups, context scopes, composed workflows, streaming, cancellation, and local state restore share the same execution model.

@motif-ts/core
Plus@conf-ts/expression

Canonical Spec & Durable Runs

Spec defines the canonical JSON workflow format and revision-checked edits. Runtime validates and compiles it against trusted implementations, authorizes actions, and provides the durable run kernel: replayable events, JSON checkpoints, and an effect journal for recovery.

@motif-ts/spec@motif-ts/runtime

Agentic Layer

Agent-facing descriptions, validated actions, tool catalogs, planner prompts, and a budgeted agent loop. Also owns goals, host run status and commands, failure classification, fallback decisions, and checkpoint, approval, and recovery hooks. Snapshots support local rewind; your application supplies LLM calls and dispatches host hooks.

@motif-ts/agentic (private preview)

Visualizer & Run Replay

Live workflow graphs, a visual spec editor, and durable-run tooling: scrub any run frame by frame from its event log, review planner re-decides as a visual spec diff, and fold many runs into visit counts and failure heat.

@motif-ts/visualizer (private preview)

Production Middleware

Composable wrappers for timeouts, retry with backoff, tracing, cost budgets, approval gates, rate limits, DevTools, and state persistence. Retry uses Agentic’s failure classifier; wrappers subscribe to Core’s lifecycle and events.

@motif-ts/middleware

Framework Adapters

Bind the same workflow to any UI with one hook, composable, or store. The engine never imports a framework — adapters subscribe to it.

@motif-ts/react@motif-ts/vue@motif-ts/svelte

Quick Start

Install, define steps, and run your workflow.

Install core and its dependencies.

Terminal
pnpm add @motif-ts/core zod zustand
# Optional React adapter
pnpm add @motif-ts/react