惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LangChain Blog
量子位
GbyAI
GbyAI
B
Blog RSS Feed
月光博客
月光博客
人人都是产品经理
人人都是产品经理
腾讯CDC
Recent Announcements
Recent Announcements
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
The Cloudflare Blog
D
Docker
Cyberwarzone
Cyberwarzone
U
Unit 42
NISL@THU
NISL@THU
C
Check Point Blog
B
Blog
大猫的无限游戏
大猫的无限游戏
Cisco Talos Blog
Cisco Talos Blog
Recorded Future
Recorded Future
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
G
GRAHAM CLULEY
Engineering at Meta
Engineering at Meta
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
P
Proofpoint News Feed
F
Fortinet All Blogs
V
V2EX
T
Threat Research - Cisco Blogs
T
Threatpost
S
SegmentFault 最新的问题
Know Your Adversary
Know Your Adversary
雷峰网
雷峰网
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 司徒正美
P
Privacy & Cybersecurity Law Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
TaoSecurity Blog
TaoSecurity Blog
Latest news
Latest news
Apple Machine Learning Research
Apple Machine Learning Research
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Y
Y Combinator Blog
P
Privacy International News Feed
L
Lohrmann on Cybersecurity
AWS News Blog
AWS News Blog
G
Google Developers Blog
美团技术团队

Workflow SDK Documentation

Patterns for Defining Tools Human-in-the-Loop Building Durable AI Agents Queueing User Messages Resumable Streams Sleep, Suspense, and Scheduling Streaming Updates from Tools API Reference Workflow Globals Changelog Resilient run start Cookbook Building a World Deploying Astro Express Fastify Hono Getting Started NestJS Next.js Nitro Nuxt Python SvelteKit Vite corrupted-event-log fetch-in-workflow hook-conflict Errors node-js-module-in-workflow serialization-failed start-invalid-workflow-function step-not-registered timeout-in-workflow webhook-invalid-respond-with-value webhook-response-not-sent workflow-not-registered Errors & Retrying Hooks & Webhooks Idempotency Foundations Serialization Starting Workflows Streaming Versioning Workflows and Steps Encryption Event Sourcing Framework Integrations Understanding Directives Migration Guides Migrating from AWS Step Functions Migrating from Inngest Migrating from Temporal Observability Testing Server-Based Testing createHook createWebhook defineHook FatalError fetch getStepMetadata getWorkflowMetadata getWritable workflow RetryableError sleep @workflow/vitest DurableAgent @workflow/ai WorkflowChatTransport getHookByToken getRun getWorld workflow/api resumeHook resumeWebhook Chat Session Modeling runtime-decryption-failed Upgrading Workflows abort-signal-timeout-in-workflow Cancellation How Cancellation Works Internal Serializable AbortController and AbortSignal Eager Processing of Steps & Incremental Event Replay TanStack Start Agent Cancellation Sequential & Parallel Execution Workflow Composition Local World | Workflow SDK Postgres World | Workflow SDK Vercel World | Workflow SDK Migrating from trigger.dev Secure Credential Handling Local World | Workflow SDK Postgres World | Workflow SDK Vercel World | Workflow SDK
How the Directives Work
2026-05-31 · via Workflow SDK Documentation

Deep dive into the internals of how Workflow SDK directives transform your code.

This is an advanced guide that dives into internals of the Workflow SDK directive and is not required reading to use workflows. To simply use the Workflow SDK, check out the getting started guides for your framework.

Workflows use special directives to mark code for transformation by the Workflow SDK compiler. This page explains how "use workflow" and "use step" directives work, what transformations are applied, and why they're necessary for durable execution.

Workflows use two directives to mark functions for special handling:

export async function handleUserSignup(email: string) {
  "use workflow"; 

  const user = await createUser(email);
  await sendWelcomeEmail(user);

  return { userId: user.id };
}

async function createUser(email: string) {
  "use step"; 

  return { id: crypto.randomUUID(), email };
}

Key directives:

  • "use workflow": Marks a function as a durable workflow entry point
  • "use step": Marks a function as an atomic, retryable step

These directives trigger the @workflow/swc-plugin compiler to transform your code in different ways depending on the execution context.

The compiler operates in three distinct modes, transforming the same source code differently for each execution context:

Comparison Table

ModeUsed InPurposeOutput API RouteRequired?
StepBuild timeBundles step handlers.well-known/workflow/v1/stepYes
WorkflowBuild timeBundles workflow orchestrators.well-known/workflow/v1/flowYes
ClientBuild/RuntimeProvides workflow IDs and types to startYour application codeOptional*

* Client mode is recommended for better developer experience—it provides automatic ID generation and type safety. Without it, you must manually construct workflow IDs or use the build manifest.

When you build your application, the Workflow SDK generates three handler files in .well-known/workflow/v1/:

flow.js

Contains all workflow functions transformed in workflow mode. This file is imported by your framework to handle workflow execution requests at POST /.well-known/workflow/v1/flow.

How it's structured:

All workflow code is bundled together and embedded as a string inside flow.js. When a workflow needs to execute, this bundled code is run inside a Node.js VM (virtual machine) to ensure:

  • Determinism: The same inputs always produce the same outputs
  • Side-effect prevention: Direct access to Node.js APIs, file system, network, etc. is blocked
  • Sandboxed execution: Workflow orchestration logic is isolated from the main runtime

Build-time validation:

The workflow mode transformation validates your code during the build:

  • Catches invalid Node.js API usage (like fs, http, child_process)
  • Prevents imports of modules that would break determinism

Most invalid patterns cause build-time errors, catching issues before deployment.

What it does:

  • Exports a POST handler that accepts Web standard Request objects
  • Executes bundled workflow code inside a Node.js VM for each request
  • Handles workflow execution, replay, and resumption
  • Returns execution results to the orchestration layer

Why a VM? Workflow functions must be deterministic to support replay. The VM sandbox prevents accidental use of non-deterministic APIs or side effects. All side effects should be performed in step functions instead.

step.js

Contains all step functions transformed in step mode. This file is imported by your framework to handle step execution requests at POST /.well-known/workflow/v1/step.

What it does:

  • Exports a POST handler that accepts Web standard Request objects
  • Executes individual steps with full runtime access
  • Returns step results to the orchestration layer

webhook.js

Contains webhook handling logic for delivering external data to running workflows via createWebhook().

What it does:

  • Exports a POST handler that accepts webhook payloads
  • Validates tokens and routes data to the correct workflow run
  • Resumes workflow execution after webhook delivery

Note: The webhook file structure varies by framework. Next.js generates webhook/[token]/route.js to leverage App Router's dynamic routing, while other frameworks generate a single webhook.js or webhook.mjs handler.

The multi-mode transformation enables the Workflow SDK's durable execution model:

  1. Step Mode (required) - Bundles executable step functions that can access the full runtime
  2. Workflow Mode (required) - Creates orchestration logic that can replay from event logs
  3. Client Mode (optional) - Prevents direct execution and enables type-safe workflow references

This separation allows:

  • Deterministic replay: Workflows can be safely replayed from event logs without re-executing side effects
  • Sandboxed orchestration: Workflow logic runs in a controlled VM without direct runtime access
  • Stateless execution: Your compute can scale to zero and resume from any point in the workflow
  • Type safety: TypeScript works seamlessly with workflow references (when using client mode)

A key aspect of the transformation is maintaining deterministic replay for workflow functions.

Workflow functions must be deterministic:

  • Same inputs always produce the same outputs
  • No direct side effects (no API calls, no database writes, no file I/O)
  • Can use seeded random/time APIs provided by the VM (Math.random(), Date.now(), etc.)

Because workflow functions are deterministic and have no side effects, they can be safely re-run multiple times to calculate what the next step should be. This is why workflow function bodies remain intact in workflow mode—they're pure orchestration logic.

Step functions can be non-deterministic:

  • Can make API calls, database queries, etc.
  • Have full access to Node.js runtime and APIs
  • Results are cached in the event log after first execution

Learn more about Workflows and Steps.

The compiler generates stable IDs for workflows and steps based on file paths and function names:

Pattern: {type}//{filepath}//{functionName}

Examples:

  • workflow//workflows/user-signup.js//handleUserSignup
  • step//workflows/user-signup.js//createUser
  • step//workflows/payments/checkout.ts//processPayment

Key properties:

  • Stable: IDs don't change unless you rename files or functions
  • Unique: Each workflow/step has a unique identifier
  • Portable: Works across different runtimes and deployments

Although IDs can change when files are moved or functions are renamed, Workflow SDK functions assume atomic versioning in the World. This means changing IDs won't break old workflows from running, but will prevent runs from being upgraded and will cause your workflow/step names to change in observability across deployments.

These transformations are framework-agnostic—they output standard JavaScript that works anywhere.

For users: Your framework handles all transformations automatically. See the Getting Started guide for your framework.

For framework authors: Learn how to integrate these transformations into your framework in Building Framework Integrations.

If you need to debug transformation issues, you can inspect the generated files:

  1. Look in .well-known/workflow/v1/: Check the generated flow.js, step.js,webhook.js, and other emitted debug files.
  2. Check build logs: Most frameworks log transformation activity during builds
  3. Verify directives: Ensure "use workflow" and "use step" are the first statements in functions
  4. Check file locations: Transformations only apply to files in configured source directories