IMPLEMENTATION_GUIDE.md

July 23, 2025 ยท View on GitHub

Implementation Guide

This document lays out technical foundations of the core element templates mechanism. Building on these foundations, a case study shows how to extend element templates with a new technical binding.

Overview

On the high level, element templates are supported through a JSON Schema and the behavior.

JSON Schema

The JSON schema is typically referenced through the $schema property in an element template descriptor. Take Camunda 8 as an example:

{
  "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json",
  "name": "Template 1",
  "id": "sometemplate",
  ...
}

The schema serves two main purposes:

  • It enables editor support (auto-completion and validation) during template creation
  • It validates templates at run-time, ensuring they are safe to use

What the schema defines must be implemented through corresponding behavior.

Behavior

Note

Recommended to build on top of bpmn-js-element-templates.

An element template implementation realizes the template behavior. It can roughtly can be structured in API, UI controls, and property bindings.

API

The API, including the elementTemplates service is used by editor integrations and the embedding applications:

  • To validate and set available templates
  • To query for applicable templates
  • To apply a template to a given diagram element
  • To create a diagram element from a template

UI Controls

Extending the properties panel, UI controls facilitate the domain specific editing of template properties, including:

  • Rendering + editing
  • Hinting
  • Validation

Property Bindings

Linking template properties to the moddle (diagram element) is realized through property bindings:

  • Established when creating a new diagram element from a template
  • Set or updated when a template changes, preserving compatible properties.
  • Retrieved from the moddle for rendering, and written back when changed through the UI

Case Study: Implementing zeebe:property

zeebe:property is a binding for Camunda 8 element templates. A element template author user can use it to create a template property bound to the zeebe:property BPMN 2.0 XML extension, i.e. on a bpmn:Task:

<bpmn:definitions>
  <bpmn:process>
    ...
    <bpmn:task>
      <bpmn:extensionElements>
        <zeebe:properties>
          <zeebe:property name="my-name" value="Walt" />
        </zeebe:properties>
      </bpmn:extensionElements>
    </bpmn:task>
    ...
  </bpmn:process>
</bpmn:definitions>

The corresponding element template descriptor could look like this:

{
  "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json",
  "name": "Template 1",
  "id": "sometemplate",
  ...
  "properties": [
    {
      "label": "My Name",
      "type": "String",
      "value": "",
      "binding": {
        "type": "zeebe:property",
        "name": "my-name"
      }
    }
  ]
}

Let's look into how this property is implemented, across schema and behavior.

Implementing zeebe:property Schema

zeebe:property is a valid value of an element templates properties binding#type field. Supporting it via JSON schema means to extend the schema appropriately to allow that value and add test coverage.

Additionally, the implementation may extend the JSON schema with custom error handling. While not relevant during template editing, the custom error handling greatly benefits users when validating element templates at run-time. It causes validators to print less technical, hence more human readable error messages.

Implementing zeebe:property Behavior

bpmn-js-element-templates implements element templates for Camunda 7 and Camunda 8. Hence, we look to the library to extend the template behavior.

What looks complicated at first realizes three aspects of the zeebe:property binding: