BPMN as Code: From a Text-Based Model to a Working Microservices Sagas

 | Deliverables

I've used Documentation as Code for years when designing backends and entire applications. Most of my diagrams are written in PlantUML, with their source stored alongside other design documents. It suits me much better than drawing everything by hand.

Then I had to model a microservices Saga for Camunda. The process involved parallel checks, deadlines, human decisions and compensation. I wanted to write BPMN the same way I wrote UML, but couldn't find a toolchain I was comfortable using. Eventually I found Mermaid-BPMN and built a workbench around it.

Contents


Issues With Conventional BPMN Tools

I tried the obvious options. I find arranging shapes in draw.io or Camunda Modeler slow, particularly when a process keeps changing. I'd rather edit source and immediately see what the diagram looks like.

BPMN XML is source too, technically. But it is cumbersome to write from scratch and not much better to edit by hand. I also looked at other BPMN DSLs. Their diagrams didn't look right to me.

I wanted readable source and conventional BPMN diagrams, including horizontal pools and lanes. I also wanted a live editor on my own host and a CLI for generating SVGs from local files. Although my implementation used Camunda, I didn't want the modeling tools tied to one process engine.

And the diagrams had to be readable by people besides developers: architects, product owners, business analysts and anyone reviewing the process.

Discovering Mermaid-BPMN

After I inspected a few other tools, I came across the great derari/mermaid-bpmn, an external Mermaid plugin with its own BPMN DSL, rich and comprehensive. It supports vertical and horizontal BPMN directions, activities, pools and lanes, gateways, events and annotations. There was also a basic live-editor example.

I liked the language and the diagrams it generated. The DSL, parser, renderer and original editor are all the original author's work. I started with that project and added what I needed for day-to-day use. The result is Mermaid BPMN Workbench.

Making It Practical

First, I packaged the editor for deployment with Docker. It builds to static files served by Nginx, so I can run it on my own host without keeping the development server running. The image is available on Docker Hub.

I then worked on the editor itself. With a large process diagram, I need to zoom in, move around and quickly return to the full view. So I added pan, zoom and fit controls. I added source-pane width presets and font-size controls, too. The source and these settings are saved in the browser and restored after a reload. There is also a clear-source button and an option to open the full SVG in a separate tab.

One detail took a little care. Pan and zoom change the SVG displayed in the editor. Exporting that modified SVG could give you the part you were looking at rather than the complete diagram. I keep a clean snapshot for downloads and the Open SVG action.

I also needed SVGs for documentation, without opening the browser editor each time. I built a Mermaid-BPMN CLI for that. It generates an svg with this one-liner.

npx mermaid-bpmn-cli --browser /path/to/chrome payment-process.mmd

It writes payment-process.svg next to the source. Currently it requires Node.js 22.12 or later and an installed Chrome or Chromium executable; you have to pass the browser path explicitly. I have used the CLI in my project's documentation workflow since that. It simplifies the workflow a lot. Also can be used in automated CI workflows for Documentation-as-Code.

A Real-World Example: Modeling a Payment Saga

The process that prompted all this was a payment Saga (here is the link to the anonymized source).

It starts by debiting the payer, then runs anti-fraud and compliance/restriction checks in parallel. The results can lead to approval, denial, manual review or suspicious-payment handling.

The checks have a 30-second deadline. If they don't finish in time, the process refunds the payer. Manual review has a 20-minute deadline, with the same default outcome if nobody makes a decision. We chose these defaults because processing an erroneous payment would cost considerably more than rejecting a valid one. I put that reasoning in annotations next to the relevant paths.

The Diagram

The Diagram

The transfer to the payee is marked as an irreversible pivot point. Earlier failures are handled by compensation: an automatic refund and a rollback of payment status. Suspicious payments also trigger a security notification in parallel with the refund, with the paths joining before the final outcome.

This is the kind of process I wanted to keep in a text file: branches, timers, compensation, and the business reasons for some of the decisions. I can change the source, review the diff and regenerate the diagram.

From BPMN Source to an Executable Saga

I also took the Saga through implementation. The microservices were deployed, the Saga coordinated them, and I tested the cases in the implemented process.

For the engine, I needed BPMN XML. I had an AI agent translate the DSL, reviewed the result myself, manually validated it and used Camunda Modeler for static debugging before deployment. I was glad to have the Modeler for that part, even though I didn't want to use it for writing the original model.

This translation step isn't a Workbench feature. The workbench gives me the source editor and SVG generation; translation, engine validation, deployment and testing are steps in my project. I checked that the executable process preserved the deadlines, branches and compensation behavior in the model.

Conclusions

I believe, this tooling is useful for any modeler - architects, developers, business analyst and product owners - all who has to model and align the business processes with the stakeholders conveniently and quickly.

You can try my hosted editor. The Workbench repository includes deployment instructions, and the CLI is on npm.

Also, it were not be possible without the Mermaid-BPMN implementation project by Derari.