Test durable workflows,
ship with confidence
An open-source lab for the Vercel Workflow DevKit. Run, inspect, and iterate on multi-step workflows -- then copy the structured output straight into v0 to build production features.
$npm i workflowHow it works
Durable functions with simple directives
Mark a function with "use workflow", split it into steps, and the runtime handles persistence, retries, and resumption.
| 1 | import { sleep } from "workflow" |
| 2 | import { generateEmail, sendEmail } from "./steps" |
| 3 | |
| 4 | export async function onboardingFlow(email: string) { |
| 5 | "use workflow" |
| 6 | |
| 7 | const welcome = await generateEmail(email, "welcome") |
| 8 | await sendEmail(welcome) |
| 9 | |
| 10 | await sleep("3d") |
| 11 | |
| 12 | const tips = await generateEmail(email, "tips") |
| 13 | await sendEmail(tips) |
| 14 | |
| 15 | await sleep("7d") |
| 16 | |
| 17 | const offer = await generateEmail(email, "offer") |
| 18 | await sendEmail(offer) |
| 19 | |
| 20 | return { emailsSent: 3 } |
| 21 | } |
Included workflows
Three workflows, ready to run
Each demonstrates different DevKit primitives -- run them, inspect step-by-step output, and read the source.
Email Drip Campaign
AI-drafted emails delivered to real inboxes via Resend, spaced by durable sleep timers that survive deploys and restarts.
await sendWelcomeEmail(contact)
await sleep("3d")
await sendTipsEmail(contact)
await sleep("7d")
await sendOfferEmail(contact)Data Pipeline
Ingest from multiple sources, validate, transform, and aggregate. AI produces an analytical report with full retry protection.
const raw = await ingestData(sources)
const valid = await validateRecords(raw)
const rows = await transformRecords(valid)
const agg = await aggregateData(rows)
return await generateReport(agg)AI Content Agent
Research, outline, pause for human approval via hooks, then write and review. Full human-in-the-loop orchestration.
const research = await researchTopic(topic)
const outline = await generateOutline(research)
await hook.suspend() // human approval
const article = await writeContent(outline)
return await reviewContent(article)Built for production
Every primitive you need
Durable Sleep
Pause for hours, days, or weeks. Timers persist across deploys, restarts, and infrastructure failures.
Automatic Retry
Steps retry on failure with configurable backoff. Distinguish permanent errors from transient ones with RetryableError.
Fault Tolerance
Step results are persisted. If a workflow restarts, completed steps replay instantly from cache -- no double-execution.
Full Observability
Inspect every run end-to-end. Trace steps, view logs, and time-travel through execution with automatic instrumentation.
Zero Config
No queues to wire, no schedulers to tune, no YAML manifests. Add directives to your existing functions and ship.
TypeScript Native
Built for TypeScript from the ground up. Full type safety across steps, hooks, and workflow inputs and outputs.
Start building durable workflows
Open the Lab to run real workflows with live output, or read the docs to start building your own.
