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 workflows using a fluent builder API with support for sequences, parallels, and gateways.

Human-in-the-Loop

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

Persistent State

Pluggable storage adapters for reliable workflow state persistence and recovery.

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
// Create deserialization context and engine
final context = RegistryDeserializationContext(
  descriptors: [DefaultWorkflowDescriptor()],
);
final engine = WorkflowEngine(
  context: context,
  storage: InMemoryStorage(context: context),
);
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: 'approvalTask',
        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'},
);