Serializable Steps
This is an advanced guide. It dives into workflow internals and is not required reading to use workflow.
When to use this pattern
Workflow functions run inside a sandboxed VM where every value that crosses a function boundary must be serializable. There are two ways to get a non-serializable object across that boundary, depending on whether you own the class:
- You own the class: implement the
WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZEprotocol. The instance becomes a first-class serializable value: you can pass it as a workflow input, return it from a step, and call"use step"instance methods on it directly. This is the right tool when the class is yours to modify. - You don't own the class: you can't add serialization methods to
openai("gpt-5.6-sol")from@ai-sdk/openaiornew S3Client({...})from@aws-sdk/client-s3. Instead, wrap construction and use in a"use step"factory function. That's what this page covers.
The problem
AI SDK provider models and cloud SDK clients often contain methods, closures, sockets, and internal state. Passing one across a workflow boundary causes a serialization error, and you can't add WORKFLOW_SERIALIZE to a class you don't own.
The solution: step-as-factory
Apply the same pattern to any non-serializable dependency. The key rule: the outer function captures serializable arguments, and the inner "use step" function constructs the real object at runtime.
A plain Vercel AI Gateway model string such as "spacexai/grok-4.6" is already serializable and does not need a factory.
AI provider example
When using an AI SDK provider package, construct and use its model inside the step. The outer factory captures only the serializable model ID:
The same structure works with provider packages such as @ai-sdk/anthropic and @ai-sdk/google: capture serializable configuration in the outer function and keep the provider object inside the step. For durable agent loops, continue to use WorkflowAgent; the factory pattern is for lower-level AI SDK calls and other third-party dependencies.
Cloud client example
Why this works
- Compiler transformation:
"use step"tells the SWC plugin to extract the function into a separate bundle. The workflow VM only sees a serializable reference (function ID and captured arguments). - Closure tracking: The compiler tracks which variables the step function closes over. The function can capture only serializable values, such as strings, numbers, and plain objects.
- Deferred construction: The step constructs the provider or client only when it executes in the Node.js runtime, never in the sandboxed workflow VM.
Key APIs
"use step": Marks a function for extraction and serialization."use workflow": Declares the orchestrator function.WorkflowAgent: Provides AI SDK's durable agent, resolves models through AI Gateway strings, and replacesDurableAgent.- AI SDK providers: Lists direct provider packages and configuration.
- Custom class serialization: Provides the companion pattern for classes you own (
WORKFLOW_SERIALIZEandWORKFLOW_DESERIALIZE).