<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jose Escrich</title>
    <description>The latest articles on DEV Community by Jose Escrich (@jose_escrich_7a9e40bdd5e7).</description>
    <link>https://dev.to/jose_escrich_7a9e40bdd5e7</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3614387%2F69f2db33-48d7-4ec5-bb4f-13d07d2b2579.png</url>
      <title>DEV Community: Jose Escrich</title>
      <link>https://dev.to/jose_escrich_7a9e40bdd5e7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jose_escrich_7a9e40bdd5e7"/>
    <language>en</language>
    <item>
      <title>Orchestrating Complex Processes in Node.js with @jescrich/nestjs-workflow</title>
      <dc:creator>Jose Escrich</dc:creator>
      <pubDate>Mon, 17 Nov 2025 01:05:15 +0000</pubDate>
      <link>https://dev.to/jose_escrich_7a9e40bdd5e7/orchestrating-complex-processes-in-nodejs-with-jescrichnestjs-workflow-jjb</link>
      <guid>https://dev.to/jose_escrich_7a9e40bdd5e7/orchestrating-complex-processes-in-nodejs-with-jescrichnestjs-workflow-jjb</guid>
      <description>&lt;p&gt;Modern backend systems are no longer simple request/response pipelines.&lt;br&gt;
They orchestrate payments, onboarding, document validation, long-running tasks, integrations with external vendors, and multi-step processes that must never end in partial failure.&lt;/p&gt;

&lt;p&gt;And yet… most Node.js applications still try to manage this complexity with:&lt;/p&gt;

&lt;p&gt;giant service classes&lt;/p&gt;

&lt;p&gt;boolean flags in the database&lt;/p&gt;

&lt;p&gt;magic strings like "pending" | "processing" | "done"&lt;/p&gt;

&lt;p&gt;ad-hoc Saga implementations&lt;/p&gt;

&lt;p&gt;hand-rolled state machines&lt;/p&gt;

&lt;p&gt;That’s why I built nestjs-workflow — a lightweight, declarative workflow engine for NestJS that helps you structure multi-step business processes with clarity, resiliency, and observability.&lt;/p&gt;

&lt;p&gt;🚀 Why nestjs-workflow?&lt;/p&gt;

&lt;p&gt;Because every real system eventually needs workflows.&lt;/p&gt;

&lt;p&gt;When you’re building microservices, event-driven systems, or anything that depends on external APIs, you need:&lt;/p&gt;

&lt;p&gt;State transitions (from “received” → “validated” → “processed” → “completed”)&lt;/p&gt;

&lt;p&gt;Retries &amp;amp; compensation when external calls fail&lt;/p&gt;

&lt;p&gt;Idempotency&lt;/p&gt;

&lt;p&gt;Persistence of state&lt;/p&gt;

&lt;p&gt;Visibility into where the process is stuck&lt;/p&gt;

&lt;p&gt;In enterprise systems (fintech, ecommerce, LOS/OMS integrations, KYC flows, etc.), this becomes even more important.&lt;/p&gt;

&lt;p&gt;nestjs-workflow gives you all of that without turning your project into a distributed-systems PhD.&lt;/p&gt;

&lt;p&gt;🧩 A Declarative Workflow, Not a Mess&lt;/p&gt;

&lt;p&gt;Here’s what a workflow looks like with the library:&lt;/p&gt;

&lt;p&gt;@Workflow()&lt;br&gt;
export class OnboardingWorkflow extends WorkflowBase {&lt;br&gt;
  definition = {&lt;br&gt;
    id: 'onboarding',&lt;br&gt;
    initial: 'received',&lt;br&gt;
    states: {&lt;br&gt;
      received: {&lt;br&gt;
        on: {&lt;br&gt;
          VALIDATE: 'validating',&lt;br&gt;
        },&lt;br&gt;
      },&lt;br&gt;
      validating: {&lt;br&gt;
        invoke: async (ctx) =&amp;gt; this.validateUser(ctx),&lt;br&gt;
        on: {&lt;br&gt;
          SUCCESS: 'completed',&lt;br&gt;
          FAILURE: 'failed',&lt;br&gt;
        },&lt;br&gt;
      },&lt;br&gt;
      failed: {},&lt;br&gt;
      completed: {},&lt;br&gt;
    },&lt;br&gt;
  };&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Clean. Explicit. Testable.&lt;br&gt;
Your workflow logic is the source of truth, not scattered across your services.&lt;/p&gt;

&lt;p&gt;🔌 Plugged Into NestJS the Right Way&lt;/p&gt;

&lt;p&gt;nestjs-workflow integrates seamlessly:&lt;/p&gt;

&lt;p&gt;✔️ Providers &amp;amp; Dependency Injection&lt;/p&gt;

&lt;p&gt;Inject services, repositories, and external clients directly into your workflow.&lt;/p&gt;

&lt;p&gt;✔️ Persistence Layer&lt;/p&gt;

&lt;p&gt;Use memory, Redis, SQL, or your own implementation.&lt;/p&gt;

&lt;p&gt;✔️ Event Emitters&lt;/p&gt;

&lt;p&gt;React to workflow transitions, notify other services, or publish Kafka messages.&lt;/p&gt;

&lt;p&gt;✔️ Hooks for Observability&lt;/p&gt;

&lt;p&gt;Perfect for platforms like Datadog, New Relic, or WHAWIT.&lt;/p&gt;

&lt;p&gt;⚙️ Real-World Example: A Payment Flow&lt;br&gt;
await this.workflowService.send('payment', orderId, 'AUTHORIZE');&lt;/p&gt;

&lt;p&gt;Behind the scenes:&lt;/p&gt;

&lt;p&gt;State moves from created → authorizing&lt;/p&gt;

&lt;p&gt;The workflow calls an external PSP&lt;/p&gt;

&lt;p&gt;If it fails, retries happen&lt;/p&gt;

&lt;p&gt;If it still fails, compensation logic runs&lt;/p&gt;

&lt;p&gt;Workflow transitions to failed&lt;/p&gt;

&lt;p&gt;Your system stays consistent&lt;/p&gt;

&lt;p&gt;This is the power of structured orchestration.&lt;/p&gt;

&lt;p&gt;🏢 Designed From Real Enterprise Problems&lt;/p&gt;

&lt;p&gt;I originally built this library after hitting the same issues repeatedly while building:&lt;/p&gt;

&lt;p&gt;event-driven ecommerce platforms&lt;/p&gt;

&lt;p&gt;financial onboarding pipelines&lt;/p&gt;

&lt;p&gt;data ingestion engines&lt;/p&gt;

&lt;p&gt;vendor adapter layers&lt;/p&gt;

&lt;p&gt;long-lived loan origination flows (LOS)&lt;/p&gt;

&lt;p&gt;background processors for Kafka/Flink&lt;/p&gt;

&lt;p&gt;Node.js needed something opinionated but flexible — a workflow engine that Team Leads and Architects could adopt without a massive learning curve.&lt;/p&gt;

&lt;p&gt;nestjs-workflow is intentionally simple, predictable, and battle-tested in production environments.&lt;/p&gt;

&lt;p&gt;📦 Explore the Examples&lt;/p&gt;

&lt;p&gt;If you want to see real, runnable use cases, check the examples repo:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/jescrich/nestjs-workflow" rel="noopener noreferrer"&gt;https://github.com/jescrich/nestjs-workflow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 (Examples moved here) &lt;a href="https://github.com/jescrich/nestjs-workflow" rel="noopener noreferrer"&gt;https://github.com/jescrich/nestjs-workflow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’ll find:&lt;/p&gt;

&lt;p&gt;Saga examples&lt;/p&gt;

&lt;p&gt;E2E workflows&lt;/p&gt;

&lt;p&gt;External service orchestration&lt;/p&gt;

&lt;p&gt;Error-handling patterns&lt;/p&gt;

&lt;p&gt;Kafka + workflow patterns&lt;/p&gt;

&lt;p&gt;Complex state machines with branching logic&lt;/p&gt;

&lt;p&gt;🎯 Final Thoughts&lt;/p&gt;

&lt;p&gt;If your NestJS application has:&lt;/p&gt;

&lt;p&gt;business processes with multiple steps&lt;/p&gt;

&lt;p&gt;integrations that may fail or require retries&lt;/p&gt;

&lt;p&gt;state transitions&lt;/p&gt;

&lt;p&gt;workflows that need transparency&lt;/p&gt;

&lt;p&gt;or just too much chaos in service layers…&lt;/p&gt;

&lt;p&gt;…then you’ll benefit from nestjs-workflow.&lt;/p&gt;

&lt;p&gt;It gives teams a clean, maintainable way to orchestrate complexity, brings structure to long-running processes, and avoids the hidden traps of “just manually coding it.”&lt;/p&gt;

&lt;p&gt;If you build something with it, tag me — I’m always curious to see how others push workflow engines to new places.&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>javascript</category>
      <category>kafka</category>
      <category>bullmq</category>
    </item>
  </channel>
</rss>
