First party fragmentStripeFormsWorkflowsUploadsAuth

Durable Workflows

Define long-running processes with steps, timers, events, and retries.

Install

npm install @fragno-dev/workflows @fragno-dev/db

Durable steps + retries

Run long-lived workflows with durable state stored in your database.

Timers + event waits

Pause for events, schedule timers, and resume exactly where you left off.

HTTP API + CLI

Create, inspect, and control workflows via HTTP routes and the fragno-wf CLI.

Setup blueprint

Define workflows, wire the fragment, and start processing.

1. Install

Install the workflows fragment and database package.

npm install @fragno-dev/workflows @fragno-dev/db

2. Define a workflow

Create a workflow with events, timers, and durable steps.

import { defineWorkflow } from "@fragno-dev/workflows";export const ApprovalWorkflow = defineWorkflow(  { name: "approval-workflow" },  async (event, step) => {    const approval = await step.waitForEvent("approval", {      type: "approval",      timeout: "15 min",    });    await step.sleep("cooldown", "2 s");    return { approved: approval.payload?.approved };  },);export const workflows = { approval: ApprovalWorkflow } as const;

3. Create the fragment server

Instantiate the fragment and attach the workflow runner.

import { defaultFragnoRuntime, instantiate } from "@fragno-dev/core";import { createWorkflowsRunner, workflowsFragmentDefinition, workflowsRoutesFactory } from "@fragno-dev/workflows";const fragment = instantiate(workflowsFragmentDefinition)  .withConfig({ workflows, runtime: defaultFragnoRuntime, enableRunnerTick: true })  .withRoutes([workflowsRoutesFactory])  .withOptions({ databaseAdapter })  .build();const runner = createWorkflowsRunner({ fragment, workflows, runtime: defaultFragnoRuntime });

Trigger runs

Use the HTTP API to create instances and send events.

const baseUrl = "/api/workflows";await fetch(`${baseUrl}/workflows/approval/instances`, {  method: "POST",  headers: { "content-type": "application/json" },  body: JSON.stringify({ requestId: "req_123", amount: 200 }),});await fetch(`${baseUrl}/workflows/approval/instances/inst_123/events`, {  method: "POST",  headers: { "content-type": "application/json" },  body: JSON.stringify({ type: "approval", approved: true }),});

Next steps

Explore the HTTP surface and runner/dispatcher options.

Workflow gallery

Real examples inspired by the workflow runner tests.

Retry workflow

Retry a failed step with constant backoff.

const RetryWorkflow = defineWorkflow(  { name: "retry-workflow" },  async (_event, step) => {    return await step.do(      "retry-step",      { retries: { limit: 1, delay: "40 ms", backoff: "constant" } },      () => {        if (Math.random() < 0.5) {          throw new Error("RETRY_ME");        }        return { ok: true };      },    );  },);

CLI control

Inspect workflows and send events without building custom dashboards.

fragno-wf workflows list -b https://host.example.com/api/workflowsfragno-wf instances create -b https://host.example.com/api/workflows -w approvals \  --params '{"requestId":"req_1","amount":125}'fragno-wf instances send-event -b https://host.example.com/api/workflows -w approvals \  -i inst_123 -t approval --payload '{"approved":true}'

Use cases

Approval chains

Route approvals through humans or systems with auditable history.

Background orchestration

Coordinate retries, timers, and async jobs without glue code.

Customer onboarding

Guide setup steps, wait for external events, then continue automatically.