Skip to main content

Overview

createWorld() creates a workflow runtime instance that handles state management, event sourcing, and infrastructure integration. The world abstraction allows workflows to run on different backends (Vercel, local development, or custom implementations).

Usage

import { createWorld } from 'workflow/runtime';

const world = createWorld();
The world is automatically created based on environment variables and typically doesn’t need to be manually instantiated in application code. Use getWorld() to access the current world instance instead.

Signature

function createWorld(): World
Returns: World - A world instance configured for the current environment

Environment Detection

The world type is automatically determined by:
  1. WORKFLOW_TARGET_WORLD environment variable (explicit override)
  2. VERCEL_DEPLOYMENT_ID presence (automatic Vercel detection)
  3. Default: Local development mode

Vercel World

Automatically used when deployed to Vercel or when WORKFLOW_TARGET_WORLD=vercel. Environment Variables:
WORKFLOW_VERCEL_AUTH_TOKEN
string
Vercel API authentication token
WORKFLOW_VERCEL_PROJECT
string
Vercel project ID (e.g., prj_xxx)
WORKFLOW_VERCEL_PROJECT_NAME
string
Vercel project slug (e.g., my-app)
WORKFLOW_VERCEL_ENV
string
Target environment: production, preview, or development
WORKFLOW_VERCEL_TEAM
string
Vercel team ID (optional, for team projects)

Local World

Used for local development when WORKFLOW_TARGET_WORLD=local or when no Vercel environment is detected. Environment Variables:
WORKFLOW_LOCAL_DATA_DIR
string
Directory for storing workflow state (defaults to .workflow-data)

Custom World

You can implement a custom world by setting WORKFLOW_TARGET_WORLD to a module path:
WORKFLOW_TARGET_WORLD=./my-custom-world.js
The module must export one of:
  • Default function returning a World instance
  • Named createWorld function

World Interface

The World interface provides access to workflow infrastructure:
interface World {
  // Event sourcing
  events: {
    create(runId: string, event: Event): Promise<{ event: Event; run: WorkflowRun }>;
  };

  // Run management
  runs: {
    get(runId: string): Promise<WorkflowRun>;
  };

  // Queue operations
  queue(queueName: string, payload: unknown, options?: QueueOptions): Promise<void>;
  createQueueHandler(prefix: string, handler: Function): Function;

  // Deployment info
  getDeploymentId(): Promise<string>;

  // Encryption (optional)
  getEncryptionKeyForRun?(run: WorkflowRun | string, context?: any): Promise<Uint8Array | undefined>;
}

getWorld()

Retrieves the singleton world instance, creating it if necessary.
import { getWorld } from 'workflow/runtime';

const world = getWorld();

setWorld()

Replaces the cached world instance. Useful for testing.
import { setWorld } from 'workflow/runtime';

setWorld(customWorld);
world
World | undefined
The world instance to use, or undefined to clear the cache

getWorldHandlers()

Retrieves world handlers needed at build time without full initialization.
import { getWorldHandlers } from 'workflow/runtime';

const handlers = getWorldHandlers();
const queueHandler = handlers.createQueueHandler('__prefix_', async (msg) => {
  // Handle message
});

Examples

Basic Usage

import { getWorld } from 'workflow/runtime';

// Get the current world (auto-created if needed)
const world = getWorld();

// Access run information
const run = await world.runs.get('wrun_123');
console.log('Status:', run.status);

Testing with Custom World

import { setWorld } from 'workflow/runtime';
import { createLocalWorld } from '@workflow/world-local';

// Use local world for testing
const testWorld = createLocalWorld({
  dataDir: './test-data',
});

setWorld(testWorld);

// Run tests...

// Clean up
setWorld(undefined);

Vercel Deployment

# .env.production
WORKFLOW_VERCEL_AUTH_TOKEN=your-token
WORKFLOW_VERCEL_PROJECT=prj_xxx
WORKFLOW_VERCEL_PROJECT_NAME=my-app
WORKFLOW_VERCEL_ENV=production
// Automatically uses Vercel world when deployed
import { getWorld } from 'workflow/runtime';

const world = getWorld(); // Returns Vercel world

Custom World Implementation

// custom-world.ts
import type { World } from '@workflow/world';

export function createWorld(): World {
  return {
    events: {
      async create(runId, event) {
        // Custom event storage
        const stored = await myDatabase.insertEvent(runId, event);
        const run = await this.runs.get(runId);
        return { event: stored, run };
      },
    },
    runs: {
      async get(runId) {
        return await myDatabase.getRun(runId);
      },
    },
    async queue(queueName, payload) {
      await myQueue.enqueue(queueName, payload);
    },
    createQueueHandler(prefix, handler) {
      return myQueue.createHandler(prefix, handler);
    },
    async getDeploymentId() {
      return process.env.DEPLOYMENT_ID || 'local';
    },
  };
}
# Use custom world
WORKFLOW_TARGET_WORLD=./custom-world.js

Type Definitions

WorkflowRun

interface WorkflowRun {
  runId: string;
  workflowName: string;
  status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
  createdAt: Date;
  startedAt?: Date;
  completedAt?: Date;
  output?: any;
  error?: {
    message: string;
    stack?: string;
  };
}

Event

type Event = 
  | { eventType: 'run_created'; eventData: { workflowName: string; input: any; ... } }
  | { eventType: 'run_started'; specVersion: number }
  | { eventType: 'run_completed'; eventData: { output: any } }
  | { eventType: 'run_failed'; eventData: { error: { message: string; stack?: string } } }
  | { eventType: 'run_cancelled'; specVersion: number }
  | { eventType: 'wait_created'; correlationId: string; eventData: { resumeAt: Date } }
  | { eventType: 'wait_completed'; correlationId: string }
  // ... and more event types

Best Practices

  1. Use getWorld() instead of createWorld(): The singleton pattern ensures consistency
  2. Environment-specific configuration: Use environment variables for different deployments
  3. Don’t cache world references: Always call getWorld() to get the current instance
  4. Test with local world: Use local world for development and testing
  5. Custom worlds for special cases: Implement custom worlds for unique infrastructure needs

See Also

Build docs developers (and LLMs) love