Skip to content

Overview

@synkro/core is a lightweight workflow and state machine orchestrator. It gives you pub/sub events, sequential workflows with conditional routing, retries with backoff, schema validation, middleware, scheduled events, and more — all backed by Redis or an in-memory transport.

When to use it

  • You need event-driven communication between services or modules.
  • You want multi-step workflows with branching, retries, and timeouts.
  • You need workflow chaining, cancellation, and state inspection at runtime.
  • You prefer a code-first orchestrator over heavyweight BPM tools.

Features

FeatureDescription
Events (pub/sub)Register handlers, publish events, remove handlers at runtime.
WorkflowsSequential multi-step workflows with state persistence.
Conditional routingonSuccess / onFailure branching per step.
Workflow chainingTrigger follow-up workflows on completion or failure.
Retries with backoffFixed or exponential backoff, jitter, retryable filter.
Schema validationValidate payloads at publish and dispatch time.
Event versioningVersioned events with automatic base-channel fanout.
MiddlewareKoa-style onion model wrapping every handler.
Scheduled eventsOne-shot delays and recurring schedules.
TimeoutsPer-workflow and per-step timeout enforcement.
Graceful shutdownDrain in-flight handlers before disconnecting.
Dead letter queueFailed messages stored for inspection and replay.
Workflow state queryInspect workflow progress at any time.
Workflow cancellationCancel running workflows programmatically.

Installation

Terminal window
npm install @synkro/core

Quick start

  1. Install the package

    Terminal window
    npm install @synkro/core
  2. Create an instance and register a handler

    import { Synkro } from "@synkro/core";
    const synkro = await Synkro.start({
    transport: "in-memory",
    });
    synkro.on("user:created", async (ctx) => {
    console.log("New user:", ctx.payload);
    });
    await synkro.publish("user:created", { name: "Alice" });
  3. Shut down gracefully

    await synkro.stop();

Next steps