All projects

bpmn-dsl-kotlin

Completed

A Kotlin DSL that compiles BPMN 2.0 collaborations to an immutable AST, validates them, and emits renderable XML — with a Flowable deployment path.

Language
Kotlin
Version
0.1.0
Updated
2026-10-01
KotlinBPMN

What it does

bpmn-dsl-kotlin authors BPMN 2.0 collaborations as Kotlin code instead of handwritten XML or a drawn diagram. A bpmnCollaboration { … } block compiles to an immutable AST; BpmnValidator produces structured diagnostics with codes and remediation hints; LayeredLayoutEngine computes BPMN DI coordinates deterministically; and BpmnXmlWriter serializes semantic XML plus DI that imports into bpmn-js-class viewers with zero warnings. A Flowable adapter adds flowable: attributes through a serializer seam — the core stays vendor-neutral — and the executable buyer process deploys to Flowable.

val c = enterpriseProcurementCollaboration()
val xml = BpmnXmlWriter(FlowableExtensionSerializer)
.writeToString(c, LayeredLayoutEngine().layout(c))

The running example is a two-pool enterprise procurement collaboration between a buyer organization and an external supplier: 68 + 25 flow elements across 8 lanes, 7 message flows, 3 boundary events, an embedded subprocess, and 21 process variables. ./gradlew :bpmn-example:run writes a 55 KB .bpmn file that bpmn-moddle parses and headless bpmn-js renders (153 elements) — both with zero warnings.

Why I built it

It is the supporting project for the tutorial series Building a Type-Safe Kotlin DSL for BPMN 2.0 — each chapter maps to one module. Beyond that, it exists because generated workflows need an authoring format that a compiler and a diff reviewer can both check: a 60-line Kotlin declaration is reviewable, refactorable, and testable in ways a 50 KB XML file or a modeler export is not.

Key features

  • Type-safe internal DSL — @DslMarker scope control with separate node-container and flow-container scopes: a lane cannot own a sequence flow and a boundary event cannot appear inside a catch event; the compiler says so.
  • Immutable AST — sealed hierarchies of events, activities, and gateways; references are ids, not object graphs, so equality and serialization stay sane.
  • First-class validation — a diagnostic-code registry covering ids, endpoints, reachability, gateway rules, boundary attachments, lane containment, message-flow contracts, and DI invariants; the example validates with zero errors and zero warnings.
  • Deterministic layout — longest-path columns, lane-index rows, boundary events pinned to host corners, orthogonal routing with a per-pool return channel; a golden-file test guards the coordinates byte-for-byte.
  • Verified against real tooling — scripts/render-verify.mjs parses the output with bpmn-moddle and renders it in headless bpmn-js via Playwright.
  • Engine-neutral core, adapter seam — EngineExtensionSerializer is the only vendor hook; bpmn-flowable is a separate module, and the library has no third-party runtime dependencies (JDK StAX only).
  • Seven Gradle modules — bpmn-model, bpmn-dsl, bpmn-validation, bpmn-xml, bpmn-layout, bpmn-flowable, bpmn-example — so consumers can depend on exactly the layer they need.

Related Projects

Type to search the site.

↑↓ navigate⏎ openPowered by Pagefind