A reference project showcasing Vercel's Workflow SDK in TypeScript and Next.js. Each route under src/app/ demonstrates one durable-execution concept end to end.
Live demo: https://typescript-durable-function.vercel.app/
| Demo | Route | Shows |
|---|---|---|
| Basics | /basics |
Workflows, steps, sleep(), automatic retries, FatalError, run status polling |
| Retries | /retries |
maxRetries, RetryableError backoff, idempotency |
| Parallel Execution | /parallel-execution |
Composing steps with Promise.all / Promise.race, and the non-cancelled loser |
| Human-in-the-Loop | /human-in-the-loop |
A typed defineHook, resuming from a private route, and an approval timeout |
See CONCEPTS.md for the SDK's execution model, event sourcing, suspension primitives, deployment model, and a detailed reference on the "use workflow" and "use step" directives.
pnpm install
pnpm devOpen http://localhost:3000.
pnpm build # production build (includes type checking)
pnpm start # serve the production build
pnpm lint # ESLintNote:
pnpm lintcurrently fails withtypescript-eslint does not support TS 7.0— a known toolchain incompatibility, unrelated to application code.pnpm buildtype-checks cleanly.
Each demo follows the same three-part shape:
- Workflow —
src/workflows/*.tsholds the"use workflow"orchestrator and its"use step"functions. - API routes —
src/app/api/**start the workflow withstart()and read run state withgetRun(). - UI — a client component under
src/components/that triggers the workflow, tails the run's stream for live events, and polls for the final result.
withWorkflow() in next.config.ts installs the SWC plugin that compiles the directives. Without it, both directives are inert no-ops.
src/
├── app/
│ ├── api/ # start + status routes
│ ├── basics/ # demo pages (one concept per route)
│ ├── retries/
│ ├── parallel-execution/
│ └── human-in-the-loop/
├── components/ # client components, one per demo
├── lib/demos.ts # demo registry driving the sidebar
└── workflows/ # "use workflow" and "use step" functions
Deploy to Vercel and the SDK registers the required /.well-known/workflow/* routes automatically via withWorkflow().