Skip to main content

Installation

npm install @workflow/nest

Usage

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

@Module({
  imports: [WorkflowModule.forRoot()],
})
export class AppModule {}

API

WorkflowModule

NestJS module that provides workflow functionality.

WorkflowModule.forRoot(options?)

Configures and returns the workflow module.
options
WorkflowModuleOptions
Module configuration options.
options.workingDir
string
Working directory for the NestJS application.Default: process.cwd()
options.dirs
string[]
Directories to scan for workflow files.Default: ['src']
options.outDir
string
Output directory for generated workflow bundles.Default: .nestjs/workflow
options.watch
boolean
Enable watch mode for development.Default: false
options.moduleType
'es6' | 'commonjs'
SWC module compilation type.Set to 'commonjs' if your NestJS project compiles to CJS via SWC. When 'commonjs', the builder rewrites externalized imports in the steps bundle to use require() via createRequire, avoiding ESM/CJS named-export interop issues.Default: 'es6'
options.distDir
string
Directory where NestJS compiles .ts source files to .js (relative to workingDir).Used when moduleType is 'commonjs' to resolve compiled file paths. This should match the outDir in your tsconfig.json.Default: 'dist'
options.skipBuild
boolean
Skip building workflow bundles (useful in production when bundles are pre-built).Default: false

WorkflowController

Controller that handles the well-known workflow endpoints. Automatically registered by WorkflowModule.forRoot().

Routes

  • POST /.well-known/workflow/v1/step - Step execution endpoint
  • POST /.well-known/workflow/v1/flow - Workflow execution endpoint
  • ALL /.well-known/workflow/v1/webhook/:token - Webhook endpoint
  • GET /.well-known/workflow/v1/manifest.json - Workflow manifest (when WORKFLOW_PUBLIC_MANIFEST=1)

NestLocalBuilder

Builder class for generating workflow bundles in NestJS applications.
import { NestLocalBuilder } from '@workflow/nest';

const builder = new NestLocalBuilder({
  workingDir: process.cwd(),
  outDir: '.nestjs/workflow',
  dirs: ['src'],
});

await builder.build();

configureWorkflowController(outDir)

Configures the workflow controller with the output directory. Called automatically by WorkflowModule.forRoot().
outDir
string
required
Output directory where workflow bundles are generated.

Configuration Examples

Basic Configuration

app.module.ts
import { Module } from '@nestjs/common';
import { WorkflowModule } from '@workflow/nest';

@Module({
  imports: [WorkflowModule.forRoot()],
})
export class AppModule {}

Custom Directories

app.module.ts
import { Module } from '@nestjs/common';
import { WorkflowModule } from '@workflow/nest';

@Module({
  imports: [
    WorkflowModule.forRoot({
      dirs: ['src/workflows', 'src/modules'],
      outDir: 'dist/workflow',
    }),
  ],
})
export class AppModule {}

CommonJS Configuration

For NestJS projects using SWC to compile to CommonJS:
app.module.ts
import { Module } from '@nestjs/common';
import { WorkflowModule } from '@workflow/nest';

@Module({
  imports: [
    WorkflowModule.forRoot({
      moduleType: 'commonjs',
      distDir: 'dist',
    }),
  ],
})
export class AppModule {}

Production Configuration

app.module.ts
import { Module } from '@nestjs/common';
import { WorkflowModule } from '@workflow/nest';

const isProduction = process.env.NODE_ENV === 'production';

@Module({
  imports: [
    WorkflowModule.forRoot({
      skipBuild: isProduction,
      watch: !isProduction,
    }),
  ],
})
export class AppModule {}

How It Works

  1. Module Initialization: WorkflowModule.forRoot() creates a NestLocalBuilder instance
  2. Build on Init: When the module initializes (onModuleInit), it builds workflow bundles
  3. Controller Registration: Registers WorkflowController with well-known workflow routes
  4. Request Handling: Controller dynamically imports generated bundles and handles request/response conversion

Express/Fastify Compatibility

The WorkflowController automatically detects and works with both Express and Fastify adapters:
  • Converts platform-specific requests to Web API Request
  • Converts Web API Response back to platform-specific response

CommonJS Interop

When using moduleType: 'commonjs', the builder:
  1. Generates ESM workflow bundles
  2. Rewrites externalized .ts/.tsx imports to use require() via createRequire
  3. Points imports to compiled .js files in distDir
This avoids ESM/CJS interop issues with SWC’s _export() wrapper pattern.

Build Queue

Uses createBuildQueue() to prevent concurrent builds when rebuilding workflows.

Build docs developers (and LLMs) love