Workflows
Durable Workflows
Durable workflows with retries, timers, waits, and resumable state right from your own database. Inspired by Cloudflare Workflows, but usable anywhere.
Install
npm install @fragno-dev/workflows @fragno-dev/dbRuntime
Steps + events + timers
Best for
Durable orchestration
Capabilities
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.
Blueprint
Define the workflow, mount the fragment, start the durable processor.
1. Install
Install the workflows fragment and database package.
npm install @fragno-dev/workflows @fragno-dev/db2. 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 start durable hook processing.
import { defaultFragnoRuntime, instantiate } from "@fragno-dev/core";import { createDurableHooksProcessor } from "@fragno-dev/db/dispatchers/node";import { workflowsFragmentDefinition, workflowsRoutesFactory } from "@fragno-dev/workflows";const fragment = instantiate(workflowsFragmentDefinition) .withConfig({ workflows, runtime: defaultFragnoRuntime }) .withRoutes([workflowsRoutesFactory]) .withOptions({ databaseAdapter }) .build();const dispatcher = createDurableHooksProcessor([fragment], { pollIntervalMs: 2000 });dispatcher.startPolling();Examples
Retry workflow
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 }; }, ); },);Use it
CLI
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}'HTTP
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 }),});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.