Getting Started
Orchestrix is a lightweight workflow orchestration library for TypeScript.
It is designed for application-level workflows where you want a clear sequence of steps, shared execution context, retries for transient failures, compensation for rollback, and optional idempotency for side-effect-heavy operations.
What Orchestrix is good for
Orchestrix works especially well for flows like:
- payment processing
- user onboarding
- webhook handling
- inventory reservation
- provisioning sequences
- internal business processes that touch multiple services
In all of these cases, the main value is not just running steps in order. The value is making failure behavior explicit and predictable.
What you build with it
At a high level, an Orchestrix flow is:
- a named workflow
- composed of one or more steps
- executed with an input object
- producing a structured result
Each step can:
- read the flow input
- store data in the shared context
- retry automatically
- fail with a timeout
- define a compensation action
Installation
Install Orchestrix using your preferred package manager:
npm install @eddiecbrl/orchestrixOr using yarn:
yarn add @eddiecbrl/orchestrixQuick Start
Creating your first workflow is simple: define named steps, pass input to run(), and inspect the result.
import { create } from "@eddiecbrl/orchestrix";
type WelcomeInput = {
email: string;
};
const welcomeFlow = create<WelcomeInput>("welcome-user")
.step("validate", (ctx) => {
if (!ctx.input.email) {
throw new Error("Email is required");
}
})
.step("create-profile", async (ctx) => {
// Simulate database work
ctx.set("profileId", "user_123");
})
.step("send-email", async (ctx) => {
const profileId = ctx.get<string>("profileId");
console.log(`Sending welcome email to ${ctx.input.email} for profile ${profileId}`);
});
const result = await welcomeFlow.run({ email: "hello@example.com" });
console.log(result.status); // "completed"
console.log(result.steps);What happens when you call run()
When you execute a flow, Orchestrix:
- creates a fresh execution context for that run
- validates the input if a schema is configured
- checks the idempotency store if one is configured and a key is provided
- runs each step in sequence or within a parallel block
- applies retries and timeouts at the step level
- compensates previously completed steps if the flow fails
- returns a
FlowResult
This lifecycle is one of the most important ideas in the library. Orchestrix is not only about composition. It is about making execution semantics visible.
Understanding the result
The run() method does not just tell you whether execution succeeded. It returns a structured result that you can log, inspect, persist, or expose in internal tooling.
type FlowResult = {
name: string;
status: "pending" | "running" | "completed" | "failed" | "cancelled";
durationMs: number;
steps: StepResult[];
error?: unknown;
};Each step result includes:
- the step name
- its final status
- how many attempts were made
- how long it took
- the error, if it failed
That means you can answer questions like:
- which step failed?
- how many retries happened?
- how long did the workflow take?
- did compensation run after a failure?
Core Concepts
Before diving deeper, it helps to understand three building blocks:
- Flow: the container for the workflow definition and global configuration
- Step: an individual unit of work with optional retry, timeout, and compensation behavior
- Context: the shared object passed through the flow execution
Common mental model
If you are new to the library, this is the right way to think about it:
- use steps for business actions
- use context for data passed between those actions
- use retries for temporary failures
- use compensation for already-completed side effects
- use idempotency when duplicate execution would be dangerous
Next Steps
- Learn about Flows to understand the execution model.
- Read about Steps to see how retries, timeouts, and compensation are configured.
- Understand Idempotency if your flow performs external side effects.
- Explore the API Reference for the exact public surface.