Skip to main content
Workflow DevKit

Welcome to Workflow DevKit

Workflow DevKit lets you easily add durability, reliability, and observability to async JavaScript. Build apps and AI agents that can suspend, resume, and maintain state with ease.
Built by engineers at Vercel, Workflow DevKit is designed to integrate seamlessly with modern JavaScript frameworks like Next.js, SvelteKit, Nuxt, and more.

Why Workflow DevKit?

Building reliable async operations in JavaScript is hard. Workflows can fail midway, external APIs can timeout, and maintaining state across retries is complex. Workflow DevKit solves these problems by providing:

Durability

Workflows automatically persist their state. If your server crashes or restarts, workflows resume exactly where they left off.

Automatic Retries

Failed steps are automatically retried with configurable backoff strategies. No manual retry logic needed.

Observability

Built-in OpenTelemetry support gives you deep insights into workflow execution, performance, and errors.

Type Safety

Full TypeScript support with intelligent type inference. Catch errors at compile time, not runtime.

Perfect For

Workflow DevKit excels at handling complex async operations:
  • AI Agents: Build durable AI agents that can pause for external tool calls, wait for user input, or handle long-running LLM operations
  • User Onboarding: Create multi-step signup flows with emails, webhooks, and delayed follow-ups
  • Data Processing: Orchestrate ETL pipelines, batch jobs, and multi-stage transformations
  • API Orchestration: Coordinate calls to multiple external services with proper error handling
  • Human-in-the-Loop: Build workflows that pause for manual approval or user action

How It Works

Workflow DevKit uses two simple directives to mark your functions:
export async function handleUserSignup(email: string) {
  'use workflow';

  const user = await createUser(email);
  await sendWelcomeEmail(user);
  await sleep('5s');
  await sendFollowUpEmail(user);

  return { userId: user.id, status: 'onboarded' };
}

async function createUser(email: string) {
  'use step';
  return { id: crypto.randomUUID(), email };
}

async function sendWelcomeEmail(user: { id: string; email: string }) {
  'use step';
  console.log(`Sending welcome email to ${user.email}`);
}

async function sendFollowUpEmail(user: { id: string; email: string }) {
  'use step';
  console.log(`Sending follow-up email to ${user.email}`);
}

Key Features

Durable State Management

Workflows persist their execution state after each step. If your application crashes or restarts, workflows resume from the last completed step:
export async function dataProcessing(fileUrl: string) {
  'use workflow';

  const file = await downloadFile(fileUrl);      // Step 1: Persisted
  const parsed = await parseFile(file);          // Step 2: Persisted
  const validated = await validateData(parsed);  // Step 3: Persisted
  await uploadResults(validated);                // Step 4: Persisted

  return { status: 'complete', records: validated.length };
}
If the workflow fails at Step 3, it will resume from Step 3 without re-executing Steps 1 and 2.

Smart Fetch Hoisting

HTTP requests are automatically extracted and made durable. No need to wrap every fetch in a step:
export async function fetchData() {
  'use workflow';

  // This fetch is automatically hoisted and retried
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();

  return data;
}

Built-in Utilities

Workflow DevKit provides powerful utilities for common patterns:
  • sleep(duration): Pause execution for a specific duration
  • createHook(): Create resumable hooks for callbacks
  • createWebhook(): Generate webhook URLs for external services
  • getWorkflowMetadata(): Access workflow context and run information
  • getStepMetadata(): Get step execution details and retry counts

Webhooks and Hooks

Pause workflows and resume them via webhooks or custom callbacks:
import { createWebhook, sleep } from 'workflow';

export async function approvalFlow(requestId: string) {
  'use workflow';

  await notifyApprover(requestId);

  const webhook = createWebhook();
  await sendApprovalEmail(requestId, webhook.url);

  // Wait for webhook to be called or timeout after 24 hours
  const approval = await Promise.race([
    webhook,
    sleep('24h').then(() => ({ approved: false, reason: 'timeout' }))
  ]);

  if (approval.approved) {
    await processApprovedRequest(requestId);
  } else {
    await handleRejection(requestId, approval.reason);
  }
}

Framework Support

Workflow DevKit integrates seamlessly with popular JavaScript frameworks:

Next.js

Full App Router and Pages Router support

SvelteKit

Native SvelteKit integration

Nuxt

Nuxt 3 with Nitro support

Astro

Server-side workflow execution

NestJS

Enterprise-ready workflows

Vite

Universal Vite plugin

Ready to Get Started?

Jump into the quickstart guide to build your first workflow in under 5 minutes:

Quickstart Guide

Build and deploy your first durable workflow

Community & Support

GitHub Discussions

Ask questions and share your projects

Report Issues

Found a bug? Let us know

API Reference

Complete API documentation

Examples

Real-world workflow examples

Build docs developers (and LLMs) love