Skip to content

Your BPMN. In Code.
Validated. AI‑ready.

Generate type-safe APIs, validate architecture rules, and make your BPMN models AI-ready — straight from your build.

auto-switching
subscription.bpmn diagram
// Generated by bpmn-to-code — do not editpackage de.emaarco.subscription object SubscriptionProcessApi { const val PROCESS_ID: String = "subscription" const val PROCESS_ENGINE: String = "ZEEBE" object Elements { const val START_EVENT_SUBMIT_REGISTRATION_FORM: String = "StartEvent_SubmitRegistrationForm" const val SERVICE_TASK_INCREMENT_SUBSCRIPTION_COUNTER: String = "serviceTask_incrementSubscriptionCounter" const val SUB_PROCESS_CONFIRMATION: String = "SubProcess_Confirmation" const val ACTIVITY_SEND_CONFIRMATION_MAIL: String = "Activity_SendConfirmationMail" const val TIMER_EVERY_DAY: String = "Timer_EveryDay" const val END_EVENT_REGISTRATION_COMPLETED: String = "EndEvent_RegistrationCompleted" } object Messages { const val MESSAGE_FORM_SUBMITTED: String = "Message_FormSubmitted" } object Timers { val TIMER_EVERY_DAY: BpmnTimer = BpmnTimer("Duration", "PT1M") }}
class SubscriptionRulesTest { @Test fun `subscription process passes architecture rules`() { // when: validating the shared BPMN file val result = BpmnValidator .fromClasspath("bpmn/subscription.bpmn") .engine(ProcessEngine.CAMUNDA_7) .withRules( BpmnRules.MISSING_SERVICE_TASK_IMPLEMENTATION, BpmnRules.MISSING_MESSAGE_NAME, BpmnRules.MISSING_ELEMENT_ID, ) .validate() // then: no errors or violations result.assertNoErrors() result.assertNoViolations("missing-service-task-implementation") result.assertNoViolations("missing-message-name") }}
{ "processId": "subscription", "flowNodes": [ { "id": "StartEvent_SubmitRegistrationForm", "displayName": "Submit subscription form", "elementType": "START_EVENT", "outgoing": ["serviceTask_incrementSubscriptionCounter"], "variables": ["subscriptionId"] }, { "id": "serviceTask_incrementSubscriptionCounter", "displayName": "Increment subscription counter", "elementType": "SERVICE_TASK", "outgoing": ["SubProcess_Confirmation"], "properties": { "type": "ServiceTask", "implementationValue": "counterClass" } } ], "messages": [ { "id": "StartEvent_SubmitRegistrationForm", "name": "Message_FormSubmitted" } ]}
compatibility
enginesZeebeCamunda 7CIB7Operaton
languagesKtKotlinJvJava
1Generate · compile-time safety

BPMN strings break silently. Until runtime.

Your Zeebe and Camunda code is full of references to BPMN elements — process IDs, message names, task types. Rename one in the modeler and nothing warns you until it fails in production. bpmn-to-code generates a type-safe Process API from your .bpmn files via Gradle, Maven, or the in-browser tool.

Learn how the generated API works
✗ Beforehardcoded strings
// scattered across your codebaseclient.newCreateInstanceCommand() .bpmnProcessId("newsletterSubscription") .send() // typo? runtime error. client.newPublishMessageCommand() .messageName("Message_FormSubmitted") .send() // renamed? silent failure. @JobWorker(type = "newsletter.sendConfirmationMail")fun sendConfirmationMail() { /* ... */ }
✓ Aftergenerated Process API
import NewsletterSubscriptionProcessApi.* client.newCreateInstanceCommand() .bpmnProcessId(PROCESS_ID) .send() // rename → compiler error. client.newPublishMessageCommand() .messageName(Messages.MESSAGE_FORM_SUBMITTED) .send() @JobWorker(type = ServiceTasks.NEWSLETTER_SEND_CONFIRMATION_MAIL)fun sendConfirmationMail() { /* ... */ }
2Validate · architecture rules · in beta

Process rules erode between deploys.

Missing implementations, undefined timers, inconsistent naming — without architectural tests, BPMN quality drifts silently. The testing module ships as a JUnit-friendly rule set you drop into any project. Catch violations in your test suite, not in staging.

See the validation rules
$ ./gradlew testFAILED
✗ missing-service-task-implementationService task "Activity_SendWelcomeMail" has no implementation.✗ missing-message-nameMessage on "StartEvent_Submit" has no name.✗ missing-element-idGateway at row 3 has no id attribute.✗ service-task-namingTask "incrementCounter" should start with "Activity_".
4 violationsbuild blocked
$ ./gradlew testPASSED
✓ missing-service-task-implementationAll service tasks wired to a worker.✓ missing-message-nameAll messages named.✓ missing-element-idEvery element has a stable id.✓ service-task-namingNaming convention enforced.
4 rules validatedready to ship
3Surface · context for your AI · in beta

Agents can’t read your .bpmn file.

Raw BPMN is 80% rendering metadata — shapes, bounds, waypoints. Agents waste context on pixels instead of process logic. bpmn-to-code emits a semantic JSON model built for AI context, not for diagrams, and exposes it over an MCP server your agent can query directly.

Read the JSON surface spec
⚠ raw BPMNrendering metadata noise
<bpmndi:BPMNShape id="Event_12xytcj_di" bpmnElement="StartEvent_SubmitRegistrationForm"> <dc:Bounds x="42" y="302" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="16" y="345" width="88" height="27" /> </bpmndi:BPMNLabel></bpmndi:BPMNShape> <bpmndi:BPMNEdge id="Flow_1csfyyz_di"> <di:waypoint x="78" y="320" /> <di:waypoint x="155" y="320" /> <di:waypoint x="155" y="200" /> <di:waypoint x="230" y="200" /></bpmndi:BPMNEdge> <!-- ~200 more lines of diagram interchange -->
✓ bpmn-to-code JSONsemantic model
{ "id": "StartEvent_SubmitRegistrationForm", "displayName": "Submit newsletter form", "elementType": "START_EVENT", "outgoing": ["Activity_IncrementCounter"], "messages": ["Message_FormSubmitted"]},{ "id": "SubProcess_Confirmation", "displayName": "Subscription Confirmation", "elementType": "SUB_PROCESS", "children": ["Activity_SendConfirmationMail", "Activity_ConfirmRegistration", "Timer_EveryDay"], "outgoing": ["Activity_SendWelcomeMail"]} // Nodes · flows · names. Nothing else.
4Ship · with Agent Skills · in beta

Build processes with agents, not around them.

Drop-in agent skills, built on everything bpmn-to-code offers. Integrate the plugin into your project in one prompt, scaffold process services from a diagram, and get architectural tests written for you — while you focus on modeling the business logic. Works with Claude Code and any other agent supporting the agentskills.io standard.

See all skills
create-process-service

Create a complete Spring Boot process service from a BPMN file — hexagonal layers, workers, Docker Compose, all wired to the generated Process API.

build-bpmn-styleguide

Build a project-specific BPMN style guide with an interactive wizard, then let the agent validate every new diagram against it.