Skip to content

Vyuh Workflow Engine

Business Process Orchestration

A powerful, extensible workflow engine for Dart and Flutter applications. Build complex business processes, approval flows, and stateful automations with a clean, composable API.

Why Workflow Engine?

Visual Process Modeling

Define executable workflows with a fluent builder or load persisted workflow definitions from storage.

Human-in-the-Loop

Built-in support for user tasks, approvals, and signal-based interactions.

Persistent State

Storage repositories persist definitions, instances, user tasks, and append-only workflow events.

Fully Extensible

Type registries for custom task executors, conditions, signals, and more.

Getting Started

Core Concepts

Node Types

NodePurpose
Start/EndEntry and exit points
TaskAutomated tasks
User TaskHuman interactions
Signal WaitWait for external events
GatewaysBranching and merging

Patterns & Examples

Quick Example

dart
final context = RegistryTypeResolver(
  descriptors: [DefaultWorkflowDescriptor()],
);

final engine = WorkflowEngine(
  context: context,
  storage: InMemoryStorage(),
  executionMode: ExecutionMode.production,
);
await engine.initialize();

// Define a simple approval workflow
final workflow = WorkflowBuilder('expense-approval', 'Expense Approval')
    .start('begin')
    .task('validate-expense', execute: (ctx) async {
      return {'valid': true};
    })
    .userTask('manager-review',
        signal: 'approval_decision',
        schemaType: 'userTask.approval',
        assignToRole: 'managers',
        storeAs: 'approvalResult')
    .oneOf('decision', [
      Branch.whenTrue('approvalResult.approved', then: 'process-payment'),
      Branch.otherwise(then: 'notify-rejection'),
    ])
    .task('process-payment', execute: (ctx) async {
      return {'processed': true};
    })
    .end('completed')
    .from('decision').to('notify-rejection')
    .task('notify-rejection', execute: (ctx) async {
      return {'notified': true};
    })
    .end('rejected')
    .build();

// Register and start the workflow
engine.registerWorkflow(workflow);
final instance = await engine.startWorkflow(
  workflowCode: workflow.code,
  input: {'amount': 500, 'description': 'Conference travel'},
);

For production CDX approvals, prefer the canonical ApprovalTemplate from cdx_workflow_templates and load its stored approval definition at boot. See Approval Workflows and CDX Integration.