No infrastructure
Just a SQLite file. No Temporal cluster, no cloud service, no message broker. Add it to a single-process app, a CLI, or an AI agent.
Multi-step workflows with full type safety, automatic retries, and crash recovery — powered by SQLite, no external services required.
Why Reflow
The same four-step order pipeline, written as a plain async function and as a Reflow workflow. Hit Kill the process mid-run — a deploy, an OOM, a laptop asleep — and watch what each one does when it comes back.
async function$0.00 spentimport { createWorkflow, createEngine } from 'reflow-ts'
import { SQLiteStorage } from 'reflow-ts/sqlite-node'
import { z } from 'zod'
const orderWorkflow = createWorkflow({
name: 'order-fulfillment',
input: z.object({ orderId: z.string(), amount: z.number() }),
})
.step('charge', async ({ input }) => {
const charge = await stripe.charges.create({ amount: input.amount })
return { chargeId: charge.id }
})
.step('fulfill', async ({ prev }) => {
const shipment = await warehouse.ship(prev.chargeId)
return { trackingNumber: shipment.tracking }
})
.step('notify', async ({ prev, input }) => {
await email.send(input.orderId, `Shipped! Track: ${prev.trackingNumber}`)
})
const engine = createEngine({ storage: new SQLiteStorage('./workflows.db'), workflows: [orderWorkflow] })
await engine.start()
await engine.enqueue('order-fulfillment', { orderId: 'ORD_123', amount: 5000 })If the process crashes after charge but before fulfill, the customer is charged exactly once and the run resumes at fulfill on restart — no double charges, no lost shipments, no manual checkpoint code.
| Reflow | Temporal | Inngest | |
|---|---|---|---|
| Infrastructure | None (SQLite file) | Server + DB | Cloud service |
| Type safety | Full end-to-end | Partial | Partial |
| Setup | bun add reflow-ts | Cluster deployment | Account + SDK |
| Best for | Single-process apps, CLIs, AI agents | Large distributed systems | Serverless |
Reflow is for solo devs and small teams who need reliable multi-step workflows without running a workflow cluster. It is not for distributed execution across many machines, sub-second dispatch latency, or shops already on Temporal.