Skip to main content
This guide shows you how to install Workflow DevKit in a NestJS project.
1

Install dependencies

Install the required packages:
npm install workflow @nestjs/common @nestjs/core
npm install -D @swc/cli @swc/core
NestJS with Workflow DevKit requires SWC for compilation. The @swc/cli and @swc/core packages are peer dependencies.
2

Initialize SWC configuration

Run the Workflow NestJS CLI to set up SWC:
npx workflow-nest init
This creates a .swcrc file with the Workflow plugin configured:
.swcrc
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true
    },
    "transform": {
      "decoratorMetadata": true
    },
    "experimental": {
      "plugins": [
        ["@workflow/swc-plugin", {}]
      ]
    }
  }
}
3

Configure the Workflow module

Import and configure the Workflow module in your app:
src/app.module.ts
import { Module } from '@nestjs/common';
import { WorkflowModule } from 'workflow/nest';
import { AppController } from './app.controller';

@Module({
  imports: [
    WorkflowModule.forRoot({
      // Optional: customize output directory
      outDir: '.nestjs/workflow',
      // Optional: skip builds in production
      skipBuild: false,
    })
  ],
  controllers: [AppController],
})
export class AppModule {}
The WorkflowModule.forRoot() method:
  • Registers the WorkflowController for handling workflow endpoints
  • Configures the builder to compile workflows
  • Sets up the output directory for workflow bundles
4

Update NestJS CLI config

Configure NestJS to use SWC for building:
nest-cli.json
{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "builder": "swc",
    "typeCheck": true
  }
}
5

Enable TypeScript support (Optional)

Add the Workflow TypeScript plugin to your tsconfig.json for IntelliSense:
tsconfig.json
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "workflow"
      }
    ]
  }
}

How it works

The NestJS integration:
  • Module system: Uses NestJS’s module system for dependency injection
  • Builder: Compiles workflows during module initialization using NestLocalBuilder
  • Controller: Provides a WorkflowController that handles workflow endpoints:
    • POST /.well-known/workflow/v1/step - Step execution
    • POST /.well-known/workflow/v1/flow - Workflow execution
    • ALL /.well-known/workflow/v1/webhook/:token - Webhook handling
    • GET /.well-known/workflow/v1/manifest.json - Manifest (when WORKFLOW_PUBLIC_MANIFEST=1)
  • Request conversion: Automatically converts Express/Fastify requests to Web API Request objects
  • Build queue: Prevents concurrent builds during module initialization

Example workflow

src/workflows/notification.ts
import { sleep } from "workflow";

export async function sendNotification(userId: string, message: string) {
  "use workflow";

  await validateUser(userId);
  await sendEmail(userId, message);
  await sleep("1 hour");
  await sendFollowUp(userId);

  return { userId, status: "sent" };
}

async function validateUser(userId: string) {
  "use step";
  console.log(`Validating user ${userId}`);
}

async function sendEmail(userId: string, message: string) {
  "use step";
  console.log(`Sending email to user ${userId}: ${message}`);
}

async function sendFollowUp(userId: string) {
  "use step";
  console.log(`Sending follow-up to user ${userId}`);
}

Triggering workflows

Start workflows from controllers:
src/app.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { start } from 'workflow/api';
import { sendNotification } from './workflows/notification';

@Controller()
export class AppController {
  @Post('notify')
  async notify(@Body() body: { userId: string; message: string }) {
    const { userId, message } = body;
    await start(sendNotification, [userId, message]);
    return { message: "Notification workflow started" };
  }
}

Development

Run the development server:
npm run start:dev
Trigger a workflow:
curl -X POST --json '{"userId":"123","message":"Hello!"}' http://localhost:3000/notify

Production

Build for production:
npm run build
Optionally skip workflow builds in production if workflows are pre-built:
src/app.module.ts
WorkflowModule.forRoot({
  skipBuild: process.env.NODE_ENV === 'production',
})

Configuration options

WorkflowModuleOptions

interface WorkflowModuleOptions {
  // Working directory for the builder (default: process.cwd())
  workingDir?: string;
  
  // Output directory for workflow bundles (default: .nestjs/workflow)
  outDir?: string;
  
  // Skip building workflow bundles (default: false)
  skipBuild?: boolean;
}

Next steps

Core Concepts

Learn about workflows and steps

API Reference

View the full NestJS API reference

Build docs developers (and LLMs) love