Skip to content
Development
Skill

/migrating-workflow-v4-to-v5

Upgrades an app from Workflow SDK 4.x to 5.0. Use when bumping the `workflow` / `@workflow/*` dependencies to v5, or when hitting removed v4 APIs — `runStep`, `stepEntrypoint`, `workflow/internal/private`, `@workflow/core/private`, `writeToStream` / `closeStream` /

From plugin
workflow
2.5k6 skills1 agent1 command

Claude Code

$ npx -y skills add vercel/workflow --skill migrating-workflow-v4-to-v5 --agent claude-code

SKILL.md

migrating-workflow-v4-to-v5.SKILL.md
name: migrating-workflow-v4-to-v5
description: >-
  Upgrades an app from Workflow SDK 4.x to 5.0. Use when bumping the `workflow` / `@workflow/*` dependencies to v5, or when hitting removed v4 APIs — `runStep`, `stepEntrypoint`, `workflow/internal/private`, `@workflow/core/private`, `writeToStream` / `closeStream` / `readFromStream` on a World, `world.steps.get` without a runId, `hook.getConflict()` returning `{ runId }`, `hook.metadata` read synchronously off a `getHookByToken()` result, `experimental_setAttributes`, `createLocalWorld` / `createVercelWorld`, `NestLocalBuilder` imported from `@workflow/nest`, or an SWC transform invoked with `mode: 'client'`.
metadata:
  author: Vercel Inc.
  version: '0.2.11'

Migrating Workflow SDK 4.x to 5.0

Workflow SDK 5.0 keeps the programming model from 4.x. `"use workflow"` / `"use step"`, `start()`, `getRun()`, hooks, webhooks, streams, `sleep()`, retries, and the event log are unchanged, so most application code compiles as-is.

The breaking changes are concentrated in three places:

1. **Runtime entrypoints** (`workflow/api`, `workflow/runtime`) — two exports removed. 2. **The `World` interface** — only relevant if the app implements a custom World or calls `getWorld()` directly. 3. **Build integrations** — `@workflow/nest` subpaths, and private compiler subpaths that were never public.

Do not rewrite workflow or step bodies. If you find yourself restructuring business logic, you have gone outside this migration.

Intake

Before editing, establish:

1. **Which packages are installed.** Read `package.json` for `workflow` and every `@workflow/*` dependency. 2. **Whether the app touches the runtime.** Grep for `getWorld`, `createWorld`, `getWorldHandlers`, `writeToStream`, `readFromStream`, `closeStream`, `listStreamsByRunId`, `getStreamChunks`, `world.steps`, `listByCorrelationId`, `runStep`, `stepEntrypoint`, `internal/private`, `core/private`. 3. **Whether the app implements a custom World.** Grep for `implements World`, `: World`, `createLocalWorld`, `createVercelWorld`, `startWorkflowWorld`. 4. **Which framework integration is in use.** `@workflow/next`, `@workflow/nest`, `@workflow/nitro`, `@workflow/sveltekit`, `@workflow/vite`, `@workflow/nuxt`, `@workflow/astro`, or the CLI. 5. **Whether `hook.getConflict()` is used.** Grep for `getConflict`. 6. **Whether hook metadata is read outside a workflow.** Grep for `getHookByToken` and `resumeHook`, then for `.metadata` on their results. 7. **Whether the app calls the compiler directly.** Grep for `mode: 'client'`, `transformSync`, `swc-plugin-workflow`. Only custom build integrations do this. 8. **Whether `experimental_setAttributes` is used.** Grep for `experimental_setAttributes`.

Report anything in 2–8 that the app does not use as "not applicable" rather than silently skipping it.

Step 1 — bump the dependencies

Move every `workflow` and `@workflow/*` dependency to `^5.0.0`. They are released together and must not be mixed across majors — a 4.x `@workflow/next` against a 5.x `workflow` will fail at build time.

{
  "dependencies": {
    "workflow": "^5.0.0",
    "@workflow/next": "^5.0.0"
  }
}

Then reinstall and rebuild so the compiler regenerates the workflow/step bundles and the generated routes under `.well-known/workflow/v1/`. Never hand-edit generated output.

Node requirements are unchanged: `^18 || ^20 || ^22 || ^24`.

Step 2 — apply the mechanical rewrites

Apply each rule only where the pattern actually appears.

`getWorld()` and `createWorld()` are async

// v4
const world = getWorld();

// v5
const world = await getWorld();

This also applies to `getWorldHandlers()`. Awaiting was already correct in 4.x, so this edit is safe to make before the dependency bump. Propagate `async` up the call chain rather than wrapping in `.then()` chains.

`createLocalWorld()` and `createVercelWorld()` removed

First-party World packages now expose a single `createWorld()` factory. The arguments are unchanged — this is a rename only.

// v4
import { createLocalWorld } from '@workflow/world-local';
const world = createLocalWorld({ dataDir });

// v5
import { createWorld } from '@workflow/world-local';
const world = createWorld({ dataDir });

The same applies to `createVercelWorld` from `@workflow/world-vercel`.

`runStep` removed from `workflow/api`

Call the step function directly. The compiler routes the call through the step runtime.

// v4
import { runStep } from 'workflow/api';
const result = await runStep(chargeCard, [orderId]);

// v5
const result = await chargeCard(orderId);

`stepEntrypoint` removed from `workflow/runtime`

Framework integrations generate step routes themselves — delete hand-written step routes that existed only to call `stepEntrypoint`. For a custom host, serve the handlers from `getWorldHandlers()` instead.

`workflow/internal/private` and `@workflow/core/private` removed

These subpaths were never public API. Remove the imports; if generated build output still references them, it is stale — reinstall and rebuild rather than restoring the imports.

Stream methods moved to `world.streams.*` with `runId` first

| v4 | v5 | | --- | --- | | `world.writeToStream(name, runId, chunk)` | `world.streams.write(runId, name, chunk)` | | `world.writeToStreamMulti(name, runId, chunks)` | `world.streams.writeMulti(runId, name, chunks)` | | `world.closeStream(name, runId)` | `world.streams.close(runId, name)` | | `world.readFromStream(name, startIndex?)` | `world.streams.get(runId, name, startIndex?)` | | `world.getStreamChunks(name, runId, options?)` | `world.streams.getChunks(runId, name, options?)` | | `world.listStreamsByRunId(runId)` | `world.streams.list(runId)` |

The argument order flipped, so a rename alone silently passes a stream name where a run ID is expected. Swap the arguments at every call site. `readFromStream` had no `runId` parameter at all — `streams.get` requires one, so thread t

Read more
@vercel
Ships withworkflow

Workflow SDK: Build durable, reliable, and observable apps and AI Agents in TypeScript

2.5k6 skills1 agent
Get the whole plugin

Stars on GitHub

Momentum

stars in total
2.5k
Star history of vercel/workflow on GitHub, a chart by star-history.com

Other skills on workflow.

internal-dev-workbench

internal-dev-workbench

Spin up a portless + tmux dev session for the Workflow SDK that gives each git worktree isolated `<branch>.<name>.localhost` URLs…

@vercel@vercelInstall Skill
migrating-to-workflow-sdk

migrating-to-workflow-…

Migrates Temporal, Inngest, Trigger.dev, and AWS Step Functions workflows to the Workflow SDK. Use when porting Activities,…

@vercel@vercelInstall Skill
migrating-world-v4-to-v5

migrating-world-v4-to-…

Upgrades a custom Workflow SDK World implementation from the v4 spec, or from a 5.0.0 beta, to the current v5 spec (spec version…

@vercel@vercelInstall Skill
workflow-init

workflow-init

Install and configure Vercel Workflow SDK before it exists in node_modules. Use when the user asks to "install workflow", "set up…

@vercel@vercelInstall Skill
workflow

workflow

Creates durable, resumable workflows using Vercel's Workflow SDK. Use when building workflows that need to survive restarts,…

@vercel@vercelInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc11d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about migrating-workflow-v4-to-v5.

Which coding agents can use migrating-workflow-v4-to-v5?
migrating-workflow-v4-to-v5 installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.