WorkflowKit:
legacy(default) — the in-memory engine you build withcreateWorkflow/WorkflowBuilder. Zero extra dependencies, runs in-process, state lives in memory.world— the Vercel Workflow SDK backed by a durable world: self-hosted Postgres (@workflow/world-postgres) or MongoDB (@workflow-worlds/mongodb). Runs survive restarts (durable replay, job queue, event log).
WorkflowKit lets you pick the engine through configuration; the default is always legacy, so existing code keeps working and legacy users never pull a single Vercel dependency.
When to use which
Use
legacy for fast in-process orchestration and local development; use world when you need durability, suspension (sleep), and resumable long-running processes.
The WorkflowKit facade
engine: "world" and providing a world config:
kit.start()/kit.stop()manage the long-lived world worker. They are no-ops onlegacy, so the same lifecycle code works for both engines.kit.run(...)dispatches to the configured engine. You can override per call:kit.run(wf, input, { engine: "world" }).
Configuration
engine: "world" without a world throws, and an unknown world.type throws.
See the WorkflowKit API reference for the full surface.
Retrieving a run’s result
A world run is durable and decoupled:kit.run(fn, args) returns a WorldRunHandle (a pass-through of the SDK Run), not the output directly. To consume it synchronously — like the legacy await workflow.run() then .result — use kit.runAndWait:
returnValue (polls until the run completes):
returnValue rejects on failure (WorkflowRunFailedError) or cancellation (WorkflowRunCancelledError), carrying the original error — so wrap it in try/catch where legacy code inspected result.status. For deferred consumption, store runId and reconstitute the handle later with getRun(runId) from workflow/api.
runAndWait works for both engines (legacy returns the workflow output; world awaits returnValue) and throws on any non-success outcome — a clean drop-in for synchronously-consumed workflows being migrated.Installing the world engine
The world engine lives in an optional package so the core stays lightweight:engine: "world" without @ai_kit/workflow-world installed, WorkflowKit throws a clear error telling you to install it.
Authoring world workflows
A world workflow is a plain async function marked with the"use workflow" directive; the real work goes in "use step" functions. These directives are detected at build time by the workflow/nitro compiler.
There is no
defineWorldStep runtime helper. The Vercel compiler only instruments directives on top-level bindings (a named function, or an arrow/function bound directly to a const). Passing the function to a wrapper call would silently break detection — the step would run as plain, non-durable code. So you write the directive yourself and (optionally) annotate with the exported types.@ai_kit/workflow-world exports WorldStep / WorldWorkflow types for ergonomics:
Control flow is native JavaScript
Because a world workflow is just an async function, you don’t need special primitives — use the language:
The
"use workflow" body must stay deterministic (no Date.now(), Math.random(), fetch, direct I/O) — put those effects inside "use step" functions.
Postgres: provision the schema once
Before the first run, the Postgres world needs its schema created (otherwise you get anundefined_table / 42P01 error). This is a one-time deployment step:
MongoDB (experimental)
The MongoDB world is community-maintained. Only the configuration changes; no application code differs from Postgres:Build & runtime constraints
The Vercel Workflow SDK requires:- A build step — Nitro compiles the
"use workflow"/"use step"functions. Add theworkflow/nitromodule to your host app’snitro.config.ts. AI Kit smooths runtime configuration but cannot remove this build step. - A long-lived worker — the world polls the database for jobs, so the world engine is not compatible with pure serverless deployments.
Migrating a legacy workflow to the world engine
Migration is a rewrite from the declarative builder to an imperative function — there is no automatic translator. Before (legacy):Feature coverage
Because theworld engine embeds the real Vercel SDK, it inherits all of its capabilities: durable execution, sleep, webhooks/hooks (human-in-the-loop), streaming, durable agents, automatic retries, and the npx workflow web observability dashboard. Advanced runtime APIs are used directly from the workflow package — the thin WorkflowKit facade only handles engine selection, lifecycle, and run dispatch.