workflow

Durable, resilient workflow execution for TypeScript, with automatic retries, persistence, and built-in observability.

Framework
npm
v4.8.5
2,378stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
84/100Excellent
Development Activity96
Maintenance100
Community68
Maturity32
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
83/100Excellent
Architecture90
Code Quality92
Innovation88
Learning Curve60

Workflow SDK turns ordinary TypeScript and JavaScript functions into durable workflows: the runtime persists progress as an event log, retries failed steps automatically, and deterministically replays code to reconstruct state after cold starts, crashes, or scale events. Workflows can suspend indefinitely - waiting on a webhook, timer, or human approval - without holding compute, then resume exactly where they left off.

The package is the top-level entry point of a larger monorepo, bundling the core runtime (@workflow/core) with a CLI, a local observability UI, and first-class integrations for Next.js, Nest, Nitro, Nuxt, SvelteKit, Astro, and Vite. It ships pluggable storage backends (“Worlds”) - a filesystem backend for local development and a managed Vercel backend for production - with a documented interface for self-hosting on Postgres or a custom backend.

What You Get

  • A durable workflow runtime that persists execution as an event log and deterministically replays it after failures, deploys, or cold starts
  • A 'use step' programming model - including a built-in hoisted fetch() - so external side effects are recorded once and never re-executed on replay
  • Framework adapters for Next.js, Nest, Nitro, Nuxt, SvelteKit, Astro, and Vite that wire the runtime into an existing app’s build and routing
  • A CLI (workflow/wf) with a local observability UI (npx workflow web) for inspecting runs, replays, and event logs during development
  • Hook and webhook resumption APIs (resumeHook, resumeWebhook) for suspending a workflow on external events without consuming compute
  • Pluggable storage backends (“Worlds”): a filesystem backend for local dev, a managed Vercel backend for production, and a documented interface for self-hosted Postgres or custom backends

Common Use Cases

  • Chaining multi-step user onboarding (verification, external API calls, delayed follow-ups) into one workflow that survives mid-run deploys
  • Checkpointing long-running AI agent tool-call loops so a crashed or redeployed process resumes exactly where it left off
  • Human-in-the-loop approval flows where a workflow suspends without compute until a reviewer resumes it via webhook or UI action
  • Replacing ad hoc queue/worker setups for background jobs that need automatic retries, backoff, and built-in observability

Under The Hood

Architecture The workflow package (packages/workflow) is a thin composition layer over @workflow/core, re-exporting the runtime (src/index.ts, src/api.ts) and a small standard library of built-in steps (src/stdlib.ts), while the core engine in packages/core does the real work: a runtime layer (src/runtime) that manages run state, replay budgets, deployment guards, and hook/webhook resumption (resume-hook.ts), a vm layer that executes workflow code inside a QuickJS WASI sandbox (quickjs-runtime.ts, quickjs-entrypoint.ts) to guarantee deterministic replay, and a serialization layer (class-serialization.ts, encryption.ts) that persists step results and workflow state as an append-only event log. Storage is abstracted behind a “World” interface (@workflow/world), with separate packages implementing filesystem-backed local development (world-local), a managed Vercel backend (world-vercel), and a simulation harness for testing (world-sim) - so what breaks if the core abstraction changes is the replay guarantee itself, since every other layer assumes the event log is the single source of truth.

Tech Stack The workspace is a pnpm/Turbo monorepo of 20+ packages built with TypeScript, targeting Node.js 22/24. The runtime layer depends on zod for schema validation, devalue and custom class-serialization for structured cloning of workflow state, nanoid/ulid for run IDs, quickjs-wasi for sandboxed deterministic execution, and @vercel/functions/@aws-sdk/credential-provider-web-identity for the managed cloud backend; semver is used internally for compatibility checks. Framework integration is handled through dedicated adapter packages (@workflow/next, @workflow/nest, @workflow/nitro, @workflow/nuxt, @workflow/sveltekit, @workflow/astro, @workflow/vite) plus a Rollup plugin and both a TypeScript language-service plugin and an SWC compiler plugin that transform 'use workflow'/'use step' directives at build time. Linting/formatting run through Biome, with Husky and lint-staged enforcing pre-commit checks.

Code Quality Testing is extensive and central to the project: packages/core alone contains 119 test files (Vitest), covering abort/replay ordering, duplicate-event handling, delivery-barrier coverage, encryption, and dedicated end-to-end and benchmark suites (e2e.test.ts, benchmark.test.ts), which signals a codebase that treats replay correctness as a first-class concern rather than an afterthought. The workflow package itself is smaller (4 test files) since it mostly re-exports core functionality. Error handling favors typed, structured errors (@workflow/errors, classify-error.ts, describe-error.ts) over silent failures, TypeScript is used throughout with strict typechecking (tsc --noEmit as a dedicated script), and CI/release automation runs through Changesets and Turbo pipelines.

API Design The public surface is deliberately close to plain async functions - workflows and steps are ordinary TypeScript functions annotated with 'use workflow'/'use step' directives (mirroring the 'use client'/'use server' convention popularized by React/Next.js), so adopting the SDK requires minimal boilerplate: install the package, add a framework integration (e.g. withWorkflow() for Next.js), and call start(). Naming is consistent across entry points (start, getRun, resumeHook, resumeWebhook), and the package bundles version-matched documentation directly inside node_modules/workflow/docs specifically so coding agents and IDEs can read accurate guides offline - a notable developer-experience touch not common in comparable SDKs.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search