Resolves the World instance for low-level storage, queuing, and streaming operations.
Retrieves the World instance for direct access to workflow storage, queuing, and streaming backends. The returned World provides low-level access to manage workflow runs, steps, events, and hooks.
Use this function when you need direct access to the underlying workflow infrastructure, such as listing all runs, querying events, or implementing custom workflow management logic.
import { getWorld } from "workflow/runtime";
const world = await getWorld(); In workflow 4.x, getWorld() is synchronous and returns World directly. It becomes async in 5.x, so writing await getWorld() works on both versions.
Parameters
This function does not accept any parameters.
Returns
Returns the World object:
| Name | Type | Description |
|---|---|---|
specVersion | number | The highest spec version this World supports.
When set, start() creates runs at this version so world-specific
features (e.g., CBOR queue transport) are enabled automatically.
When omitted, runs default to SPEC_VERSION_SUPPORTS_EVENT_SOURCING (2),
the safe baseline that all worlds — including community worlds on
older |
processExitTriggersQueueRedelivery | boolean | Whether calling process.exit(1) from a queue handler is observed by
the World as a delivery failure that will be retried.
Set to true for worlds running inside a managed serverless platform
(e.g. world-vercel) where the platform fails the invocation when the
function process exits non-zero, and the queue redelivers the message
via a separate fresh invocation.
Set to false (the default) for in-process worlds (e.g. world-local,
dev servers) where calling process.exit() would terminate the host
process — including the user's pnpm dev — without producing a
redelivery. Such worlds should instead surface failures via the event
log and return normally.
The core runtime reads this when deciding how to handle an exhausted
replay budget: when true it exits so the queue redelivers; when
false it writes run_failed best-effort and returns. See
packages/core/src/runtime/replay-budget.ts. |
start | () => Promise<void> | A function that will be called to start any background tasks needed by the World implementation. For example, in the case of a queue backed World, this would start the queue processing. |
close | () => Promise<void> | Release any resources held by the World implementation (connection pools, listeners, etc.).
After calling close(), the World instance should not be used again.
This is important for CLI commands and short-lived processes that need to exit cleanly
without relying on process.exit(). |
resolveLatestDeploymentId | () => Promise<string> | Resolve the most recent deployment ID for the current deployment's environment.
Used when deploymentId: 'latest' is passed to start(). The implementation
determines the latest deployment that shares the same environment (e.g., same
"production" target or same git branch for "preview" deployments) as the
current deployment.
Not all World implementations support this — it is only implemented by
world-vercel where deployment routing is meaningful. |
getEncryptionKeyForRun | { (run: { runId: string; deploymentId: string; workflowName: string; attributes: Record<string, string>; createdAt: Date; updatedAt: Date; status: "pending" | "running"; ... 8 more ...; completedAt?: undefined; } | { ...; } | { ...; } | { ...; }): Promise<...>; (runId: string, context?: Record<...> | undefined): Pro... | Retrieve the AES-256 encryption key for a specific workflow run.
The returned key is a ready-to-use 32-byte AES-256 key. The World
implementation handles all key retrieval and derivation internally
(e.g., HKDF from a deployment key). The core encryption module uses
this key directly for AES-GCM encrypt/decrypt operations.
Two overloads:
- getEncryptionKeyForRun(run) — Preferred. Pass a WorkflowRun when
the run entity already exists. The World reads any context it needs
(e.g., deploymentId) directly from the run.
- getEncryptionKeyForRun(runId, context?) — Used when the run entity
is not locally available, such as start() before run creation or a
forwarded writable stream carrying its owning deployment context. The
context parameter carries opaque world-specific data (e.g.,
{ deploymentId } for world-vercel) needed to resolve the correct key.
When context is omitted, the World assumes the current deployment.
When not implemented, encryption is disabled — data is stored unencrypted. |
getDeploymentId | () => Promise<string> | |
queue | (queueName: string, message: { runId: string; traceCarrier?: Record<string, string> | undefined; requestedAt?: Date | undefined; replayDivergence?: { eventId: string; count: number; } | undefined; serverErrorRetryCount?: number | undefined; stepId?: string | undefined; stepName?: string | undefined; runInput?: { ...... | Enqueues a message to the specified queue. |
createQueueHandler | (queueNamePrefix: string, handler: (message: unknown, meta: { attempt: number; queueName: string; messageId: string & $brand<"MessageId">; requestId?: string; }) => Promise<void | { timeoutSeconds: number; }>) => (req: Request) => Promise<...> | Creates an HTTP queue handler for processing messages from a specific queue. |
streamFlushIntervalMs | number | Override the default flush interval (in milliseconds) for buffered stream writes. Chunks are accumulated in a buffer and flushed together on this interval. The default is 10ms, which is appropriate for HTTP-based backends where each flush is a network round-trip. For backends with sub-millisecond writes (e.g., Redis, local filesystem), a lower value (or 0 for immediate flushing) reduces end-to-end stream latency. Not supported by all worlds. |
streams | { write(runId: string, name: string, chunk: string | Uint8Array<ArrayBufferLike>): Promise<void>; writeMulti?(runId: string, name: string, chunks: (string | Uint8Array<...>)[]): Promise<...>; ... 4 more ...; getInfo(runId: string, name: string): Promise<...>; } | |
runs | { get(id: string, params: GetWorkflowRunParams & { resolveData: "none"; }): Promise<WorkflowRunWithoutData>; get(id: string, params?: (GetWorkflowRunParams & { ...; }) | undefined): Promise<...>; get(id: string, params?: GetWorkflowRunParams | undefined): Promise<...>; list(params: ListWorkflowRunsParams & { ...; })... | |
steps | { get(runId: string, stepId: string, params: GetStepParams & { resolveData: "none"; }): Promise<StepWithoutData>; get(runId: string, stepId: string, params?: (GetStepParams & { ...; }) | undefined): Promise<...>; get(runId: string, stepId: string, params?: GetStepParams | undefined): Promise<...>; list(params: ListW... | |
events | { create(runId: string | null, data: { eventType: "run_created"; eventData: { deploymentId: string; workflowName: string; input: unknown; executionContext?: Record<string, any> | undefined; attributes?: Record<...> | undefined; allowReservedAttributes?: true | undefined; }; correlationId?: string | undefined; specVe... | |
hooks | { get(hookId: string, params?: GetHookParams | undefined): Promise<Hook>; getByToken(token: string, params?: GetHookParams | undefined): Promise<...>; list(params: ListHooksParams): Promise<...>; } |
The World object provides access to several entity interfaces. See the World SDK reference for complete documentation:
Step and run data is serialized using the devalue format. Use workflow/observability to hydrate it for display:
import { hydrateResourceIO, observabilityRevivers } from "workflow/observability";
const step = await world.steps.get(runId, stepId);
const hydrated = hydrateResourceIO(step, observabilityRevivers); See workflow/observability for the full hydration and parsing API.
List Workflow Runs (Display Names)
List workflow runs and derive human-readable names from the workflowName field:
import { getWorld } from "workflow/runtime";
import { parseWorkflowName } from "workflow/observability";
export async function GET(req: Request) {
const url = new URL(req.url);
const cursor = url.searchParams.get("cursor") ?? undefined;
try {
const world = await getWorld();
const runs = await world.runs.list({
pagination: { cursor },
resolveData: "none",
});
return Response.json({
data: runs.data.map((run) => {
const parsed = parseWorkflowName(run.workflowName);
return {
runId: run.runId,
// Use shortName for UI display (e.g., "processOrder")
displayName: parsed?.shortName ?? run.workflowName,
// Module info available for debugging
module: parsed?.moduleSpecifier,
status: run.status,
startedAt: run.startedAt,
completedAt: run.completedAt,
};
}),
cursor: runs.cursor,
});
} catch (error) {
return Response.json(
{ error: "Failed to list workflow runs" },
{ status: 500 }
);
}
}The workflowName field contains a machine-readable identifier like workflow//./src/workflows/order//processOrder.
Use parseWorkflowName() to extract the shortName (e.g., "processOrder")
and moduleSpecifier for display in your UI.












