Skip to content

Introduction & Core Concepts

This guide will walk you through creating, configuring, and managing automated processes using the @identity-flow/sdk.

IdentityFlow provides a powerful, code-first engine for defining and executing complex business processes. At its core, it leverages several key principles:

  • Event-Sourced: Every state change, decision, and action within a workflow is recorded as an immutable event. This creates a complete, auditable history of everything that happened. Learn more about Event Sourcing in our Features section.
  • Code-First: Workflows are defined directly in TypeScript using the @identity-flow/sdk. This gives you the full power and expressiveness of a familiar programming language to model complex logic.
  • Resilient & Durable: The engine is designed to handle failures gracefully. Thanks to event sourcing, workflows can resume exactly where they left off after interruptions, ensuring exactly-once execution of critical steps.
  • Transparent & Observable: With a full event log and integration with standards like OpenTelemetry, you gain deep visibility into where your workflows are and what they’ve done.
  • Deterministic Execution: Given the same input, workflows always execute the same way. Learn more about Deterministic Execution in our Features section.
  • Transparency: See exactly what happened at each step.
  • Durability: Ensure processes complete reliably, even amidst failures.
  • Auditability: Maintain a complete, immutable log for compliance and debugging.
  • Flexibility: Model complex logic using familiar TypeScript code.
  • Testability: Write unit and integration tests for your workflow logic.

Workflow Definition

A template written in TypeScript using the SDK, describing the steps, logic, and rules of a specific process.

Workflow Instance

A single, live execution of a Workflow Definition, triggered with specific input parameters. Each instance has its own state and event history.

Steps / Activities

Individual units of work within a workflow (e.g., calling an API, waiting for input, running custom logic). They are atomic and can be retried independently.

Events

Immutable records representing every state change or action that occurs during a workflow instance’s lifecycle. This underpins event sourcing.

State

The current status of a workflow instance (e.g., ACTIVE, SLEEPING, PENDING, COMPLETED, FAILED).

To follow the guides, you should have:

  • Familiarity with TypeScript and modern JavaScript (async/await).
  • Node.js (version recommended by the project) installed.
  • Access to an IdentityFlow engine environment (including the GraphQL API, typically at http://localhost:4000/graphql for local development).

Ready to build your first workflow? Let’s start with the Quick Start Guide!

A workflow is a series of steps executed in a specific order, defined as an async function.

import { defineWorkflow } from '@identity-flow/sdk';
export default defineWorkflow('order-processing', async (flow) => {
// Step 1: Validate Order
const validatedOrder = await flow.do('validate order', async () => {
return validateOrder(flow.params);
});
// Step 2: Process Payment
const payment = await flow.do('process payment', async () => {
return processPayment(validatedOrder);
});
// Step 3: Fulfill Order
await flow.do('fulfill order', async () => {
return fulfillOrder(payment);
});
});

Steps are atomic units of work within a workflow that can be retried independently.

Atomic Operations

Each step performs a single, cohesive unit of work.

Independent Retries

Steps can be retried individually on failure.

State Management

Steps maintain state through their return values.

await flow.do(
'process payment',
{
// Retry configuration
retries: { limit: 3, delay: '30 seconds', backoff: 'exponential' },
// Maximum execution time
timeout: '5 minutes',
// Unique key for idempotency
idempotencyKey: orderId,
// Step-level validation
schema: PaymentSchema,
},
async () => {
return processPayment(flow.params);
},
);

All state changes are recorded as events, providing transparency and audit trails.

export default defineWorkflow('document-approval', async (flow) => {
// Each action creates an event
await flow.do('submit document', async () => {
await submitDocument(flow.params);
// Event: DocumentSubmitted
});
await flow.do('request approval', async () => {
await requestApproval(flow.params);
// Event: ApprovalRequested
});
});

For more details, see the Event Sourcing feature page.

Given the same input, workflows always execute the same way. This ensures predictable outcomes and reliable replay for debugging.

export default defineWorkflow('order-processing', async (flow) => {
// Given the same input, this will always execute the same way
const validationResult = await flow.do('validate order', async () => {
return await validateOrder(flow.params);
});
// Conditional paths are predictable based on input
if (validationResult.approved) {
await flow.do('process order', async () => {
await processOrder(flow.params);
});
} else {
await flow.do('reject order', async () => {
await rejectOrder(flow.params, validationResult.reason);
});
}
});

For more details, see the Deterministic Execution feature page.


Continue your learning journey: