bpmn-js vs bpmn-js-properties-panel
Building Interactive BPMN 2.0 Diagram Editors in Web Applications
bpmn-jsbpmn-js-properties-panel

Building Interactive BPMN 2.0 Diagram Editors in Web Applications

bpmn-js is the core rendering and modeling engine for BPMN 2.0 diagrams in the browser. It provides the canvas, shape rendering, connection logic, and the underlying model API to create, edit, and visualize business processes. It handles the heavy lifting of translating XML into interactive SVG graphics.

bpmn-js-properties-panel is a companion library designed to work alongside bpmn-js. It provides a pre-built sidebar UI that allows users to edit the properties of selected diagram elements (such as naming a task or assigning an ID). While bpmn-js focuses on the visual graph, this package focuses on the data attributes associated with each node, bridging the gap between visual modeling and detailed configuration.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
bpmn-js09,6365.17 MB1313 days agoSEE LICENSE IN LICENSE
bpmn-js-properties-panel033712.1 MB48a day agoMIT

bpmn-js vs bpmn-js-properties-panel: Core Engine vs. Property Editor

When building process modeling tools in the browser, bpmn-js and bpmn-js-properties-panel are the two pillars of the standard stack. They solve different parts of the same problem: bpmn-js handles the visual diagram on the canvas, while bpmn-js-properties-panel handles the data configuration in the sidebar. Understanding how they interact is key to architecting a robust editor.

🎨 The Canvas: Rendering and Interaction

bpmn-js is the heart of the system. It creates the SVG canvas, manages the zoom/pan controls, and handles the drag-and-drop logic for shapes and connections. It parses BPMN 2.0 XML and turns it into interactive graphics.

Without bpmn-js, you have no diagram. It exposes the Modeler for editing and Viewer for read-only scenarios.

import BpmnModeler from 'bpmn-js/lib/Modeler';

// Initialize the core editor
const modeler = new BpmnModeler({
  container: '#canvas'
});

// Import existing BPMN XML
const xml = '<?xml version="1.0" encoding="UTF-8"?>...';

modeler.importXML(xml, function(err) {
  if (err) {
    console.error('Failed to import diagram', err);
  } else {
    // Access the underlying canvas API
    const canvas = modeler.get('canvas');
    canvas.zoom('fit-viewport');
  }
});

bpmn-js-properties-panel does not render the diagram itself. If you try to use it without bpmn-js, nothing visual will appear on the main screen. It relies entirely on the selection events fired by bpmn-js to know which element to display properties for.

// This package does NOT initialize the canvas
// It requires a container separate from the diagram
const propertiesPanelContainer = '#properties';

📝 Editing Data: Visual vs. Attribute-Based

bpmn-js allows direct manipulation of the graph. You can move tasks, redraw connections, and change basic labels directly on the canvas. However, it does not provide a UI for editing complex attributes like "Implementation Type" or "Async Before" out of the box.

To change a label directly on the canvas:

// bpmn-js handles direct canvas labeling
// Double-clicking a shape triggers this internally
const elementRegistry = modeler.get('elementRegistry');
const task = elementRegistry.get('Task_1');

// Updating the business object name directly
const modeling = modeler.get('modeling');
modeling.updateLabel(task, 'New Task Name');

bpmn-js-properties-panel shines when you need to edit specific XML attributes that don't fit on a visual label. It provides a form-based interface (typically in a sidebar) bound to the selected element's business object.

To use it, you must explicitly wire it up to the bpmn-js instance:

import BpmnPropertiesPanel from 'bpmn-js-properties-panel';
import { BpmnPropertiesProvider } from 'bpmn-js-properties-panel';

// Initialize the properties panel
const propertiesPanel = new BpmnPropertiesPanel({
  parent: document.querySelector('#properties'),
  bpmnJS: modeler, // Connects to the core engine
  providers: [BpmnPropertiesProvider]
});

// Now, clicking a task in bpmn-js populates this sidebar

🔌 Architecture: Wiring the Two Together

The most critical architectural decision is how you connect these two libraries. They do not auto-magically find each other; you must pass the bpmn-js instance into the properties panel constructor.

bpmn-js acts as the event emitter. When a user clicks a shape, it updates its internal selection service.

// bpmn-js manages the selection state
const selection = modeler.get('selection');

// Listen for selection changes to debug
selection.on('changed', function(e) {
  console.log('Selected elements:', e.newSelection);
  // The properties panel listens to this same event internally
});

bpmn-js-properties-panel acts as the subscriber. It listens to the selection changes from bpmn-js and re-renders the form inputs based on the type of the selected element (e.g., showing different fields for a "Service Task" vs. a "User Task").

// The properties panel internally subscribes to bpmn-js events
// You don't need to manually forward events if you pass bpmnJS in config
const propertiesPanel = new BpmnPropertiesPanel({
  parent: '#properties',
  bpmnJS: modeler, // This link is mandatory
  providers: [BpmnPropertiesProvider]
});

🧩 Extensibility: Adding Custom Fields

Both packages are designed to be extended, but they handle customization differently.

bpmn-js allows you to add custom palette entries (icons to drag onto the canvas) and context pad entries (actions that appear when clicking a shape).

// bpmn-js: Adding a custom palette entry
function CustomPaletteProvider(palette, create) {
  this._palette = palette;
  this._create = create;
  palette.register(this);
}

CustomPaletteProvider.prototype.createParticipant = function() {
  // Logic to create a custom shape on the canvas
};

// Register via dependency injection
const modeler = new BpmnModeler({
  container: '#canvas',
  additionalModules: [
    { paletteProvider: ['type', CustomPaletteProvider] }
  ]
});

bpmn-js-properties-panel allows you to add custom form fields to the sidebar. This is common when you need to support custom BPMN extensions (like Camunda or Zeebe specific properties).

// bpmn-js-properties-panel: Adding a custom property group
import { Group } from '@bpmn-io/properties-panel';

function CustomPropertiesProvider(elementRegistry, moddle) {
  return {
    getGroups: function(element) {
      return function(groups) {
        const customGroup = new Group({
          id: 'custom-group',
          label: 'Custom Settings',
          entries: [
            // Define inputs like text fields or dropdowns here
          ]
        });
        groups.push(customGroup);
        return groups;
      };
    }
  };
}

🗂️ Similarities: Shared Ground

While they serve different UI zones, both libraries share fundamental design principles and dependencies.

1. 🏗️ Built on Diagram.js

Both libraries rely on diagram.js as the underlying graph engine. This means they share the same coordinate system, event handling model, and command stack architecture.

// Both access the command stack to ensure undo/redo works
const commandStack = modeler.get('commandStack');

// Executing a change through the stack (used by both internally)
commandStack.execute('shape.updateProperties', {
  element: task,
  properties: { name: 'Updated Name' }
});

2. 📄 BPMN 2.0 Compliance

Both strictly adhere to the BPMN 2.0 specification. They use the moddle library to parse and validate XML structures, ensuring that whatever you edit in the properties panel results in valid BPMN XML.

// Accessing the underlying moddle instance to read raw XML attributes
const moddle = modeler.get('moddle');

// Create a new extension element
const extensionElement = moddle.create('camunda:InputOutput', {
  inputParameters: []
});

3. 🔁 Command Stack Integration

Both libraries route all changes through a central command stack. This ensures that actions taken on the canvas (moving a shape) and actions taken in the properties panel (changing a name) are both undoable.

// Undo/Redo works globally across both components
const keyboard = modeler.get('keyboard');

// Pressing Ctrl+Z undoes changes from either the canvas or the panel
keyboard.bind();

4. 🎨 Dependency Injection System

Both use a modular dependency injection system. You don't instantiate classes directly; you request services (like canvas, modeling, selection) from the container.

// Retrieving services in both contexts
modeler.invoke(function(eventBus, canvas) {
  eventBus.on('element.click', function(context) {
    console.log('Clicked:', context.element);
  });
});

5. 🌐 Framework Agnostic Core

Both libraries are vanilla JavaScript. They do not depend on React, Vue, or Angular. You can wrap them in any frontend framework, though the properties panel recently adopted a framework-agnostic web component approach for its UI rendering.

// Works in any JS environment
import BpmnModeler from 'bpmn-js/lib/Modeler';
// No React/Vue imports needed for the core logic

📊 Summary: Key Similarities

FeatureShared by Both
Core Engine🏗️ Built on diagram.js
Standard📄 Strict BPMN 2.0 compliance
State Management🔁 Unified Command Stack (Undo)
Architecture🎨 Dependency Injection System
Frameworks🌐 Vanilla JS (Framework Agnostic)
XML Handling📝 Uses moddle for parsing

🆚 Summary: Key Differences

Featurebpmn-jsbpmn-js-properties-panel
Primary Role🎨 Visual Canvas & Diagram Engine📝 Sidebar Form & Attribute Editor
User Interaction🖱️ Drag, Drop, Connect, Zoom⌨️ Type, Select, Configure
Dependency✅ Standalone❌ Requires bpmn-js instance
Output🖼️ SVG Graphics📋 Updated XML Attributes
Customization🧩 Palette & Context Pad🧩 Property Groups & Entries
Necessity🔴 Mandatory for any editor🟢 Optional (needed for data entry)

💡 The Big Picture

bpmn-js is the engine 🚗. It provides the road, the wheels, and the steering. If you want to display a process diagram or let users draw one, this is your starting point. It is non-negotiable for any BPMN project.

bpmn-js-properties-panel is the dashboard 📟. It lets the driver tune the engine settings. While you can drive without looking at the gauges (using only canvas labels), professional applications almost always require this component to allow users to configure the technical details of their processes.

Final Thought: Start with bpmn-js to get your diagram rendering. Once you realize your users need to edit more than just shape names, integrate bpmn-js-properties-panel to provide a complete, professional modeling experience.

How to Choose: bpmn-js vs bpmn-js-properties-panel

  • bpmn-js:

    Choose bpmn-js when you need to embed a full-featured BPMN 2.0 editor or viewer into your application. It is the mandatory foundation for any project requiring process visualization, drag-and-drop modeling, or XML import/export capabilities. You cannot build a functional BPMN editor without this core engine.

  • bpmn-js-properties-panel:

    Choose bpmn-js-properties-panel if your users need to edit detailed element properties (like IDs, names, or custom extensions) without writing raw XML. It is essential for production-grade editors where users expect a familiar 'properties tab' experience. If you only need a read-only viewer, you can skip this package.

README for bpmn-js

bpmn-js - BPMN 2.0 for the web

Build Status

View and edit BPMN 2.0 diagrams in the browser.

bpmn-js screencast

Installation

Use the library pre-packaged or include it via npm into your node-style web-application.

Usage

To get started, create a bpmn-js instance and render BPMN 2.0 diagrams in the browser:

const xml = '...'; // my BPMN 2.0 xml
const viewer = new BpmnJS({
  container: 'body'
});

try {
  const { warnings } = await viewer.importXML(xml);

  console.log('rendered');
} catch (err) {
  console.log('error rendering', err);
}

Checkout our examples for many more supported usage scenarios.

Resources

Build and Run

Prepare the project by installing all dependencies:

npm install

Then, depending on your use-case you may run any of the following commands:

# build the library and run all tests
npm run all

# spin up a single local modeler instance
npm start

# run the full development setup
npm run dev

You may need to perform additional project setup when building the latest development snapshot.

Related

bpmn-js builds on top of a few powerful tools:

  • bpmn-moddle: Read / write support for BPMN 2.0 XML in the browsers
  • diagram-js: Diagram rendering and editing toolkit

It is an extensible toolkit, complemented by many additional utilities.

License

Use under the terms of the bpmn.io license.