{"id":10589,"library":"bpmn-js-differ","title":"BPMN.js Differ","description":"bpmn-js-differ is a semantic diffing utility specifically designed for comparing two BPMN 2.0 files programmatically. It analyzes the structural and semantic differences between two BPMN definitions, producing a detailed report of added, removed, changed, and layout-modified elements. The current stable version is 3.2.0. The library maintains a steady release cadence, often aligning with updates to its core dependencies like `bpmn-moddle` and `bpmn-js`. Its key differentiator lies in providing a structured, semantic diff output, which is crucial for building visual diff tools or automated change detection workflows for BPMN diagrams, as opposed to simple text-based comparisons.","status":"active","version":"3.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/bpmn-io/bpmn-js-differ","tags":["javascript","bpmnjs","diff"],"install":[{"cmd":"npm install bpmn-js-differ","lang":"bash","label":"npm"},{"cmd":"yarn add bpmn-js-differ","lang":"bash","label":"yarn"},{"cmd":"pnpm add bpmn-js-differ","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required to parse BPMN 2.0 XML into definitions, which are the input for bpmn-js-differ.","package":"bpmn-moddle","optional":false},{"reason":"An internal utility library from bpmn.io, used for various helper functions.","package":"min-dash","optional":false}],"imports":[{"note":"bpmn-js-differ became an ES module in v3.0.0; CommonJS require() is not supported for versions >= 3.","wrong":"const { diff } = require('bpmn-js-differ');","symbol":"diff","correct":"import { diff } from 'bpmn-js-differ';"},{"note":"Required to parse BPMN XML into the definitions object expected by `diff`. bpmn-moddle also switched to ESM.","wrong":"const { BpmnModdle } = require('bpmn-moddle');","symbol":"BpmnModdle","correct":"import { BpmnModdle } from 'bpmn-moddle';"},{"note":"Type imports for the output of the diff function are useful for TypeScript users.","symbol":"BpmnJsDifferTypes","correct":"import type { Change, Changes } from 'bpmn-js-differ';"}],"quickstart":{"code":"import { diff } from 'bpmn-js-differ';\nimport { BpmnModdle } from 'bpmn-moddle';\n\n// Example BPMN XML strings (replace with your actual diagrams)\nconst diagramAXML = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<bpmn:definitions xmlns:bpmn=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" id=\"Definitions_1\">\n  <bpmn:process id=\"Process_1\" isExecutable=\"false\">\n    <bpmn:startEvent id=\"StartEvent_1\" name=\"Start\"></bpmn:startEvent>\n    <bpmn:task id=\"Task_1\" name=\"Original Task\"></bpmn:task>\n    <bpmn:sequenceFlow id=\"Flow_1\" sourceRef=\"StartEvent_1\" targetRef=\"Task_1\"></bpmn:sequenceFlow>\n  </bpmn:process>\n</bpmn:definitions>`;\n\nconst diagramBXML = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<bpmn:definitions xmlns:bpmn=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" id=\"Definitions_1\">\n  <bpmn:process id=\"Process_1\" isExecutable=\"false\">\n    <bpmn:startEvent id=\"StartEvent_1\" name=\"Start\"></bpmn:startEvent>\n    <bpmn:task id=\"Task_1\" name=\"Modified Task\"></bpmn:task>\n    <bpmn:endEvent id=\"EndEvent_1\" name=\"End\"></bpmn:endEvent>\n    <bpmn:sequenceFlow id=\"Flow_1\" sourceRef=\"StartEvent_1\" targetRef=\"Task_1\"></bpmn:sequenceFlow>\n    <bpmn:sequenceFlow id=\"Flow_2\" sourceRef=\"Task_1\" targetRef=\"EndEvent_1\"></bpmn:sequenceFlow>\n  </bpmn:process>\n</bpmn:definitions>`;\n\nasync function compareBpmnDiagrams(xmlA, xmlB) {\n  const bpmnModdle = new BpmnModdle();\n\n  const { rootElement: definitionsA } = await bpmnModdle.fromXML(xmlA);\n  const { rootElement: definitionsB } = await bpmnModdle.fromXML(xmlB);\n\n  const changes = diff(definitionsA, definitionsB);\n\n  console.log('Detected Changes:');\n  console.log('  Added:', Object.keys(changes._added));\n  console.log('  Removed:', Object.keys(changes._removed));\n  console.log('  Changed:', Object.keys(changes._changed));\n  console.log('  Layout Changed:', Object.keys(changes._layoutChanged));\n\n  return changes;\n}\n\ncompareBpmnDiagrams(diagramAXML, diagramBXML)\n  .catch(console.error);\n","lang":"javascript","description":"This quickstart demonstrates how to use `bpmn-js-differ` to compare two BPMN 2.0 XML strings by first parsing them with `bpmn-moddle` and then feeding the resulting definitions into the `diff` function. It then logs the detected additions, removals, modifications, and layout changes."},"warnings":[{"fix":"Migrate your module loading to `import { diff } from 'bpmn-js-differ';`. If using Node.js, ensure your project is configured for ESM (e.g., `\"type\": \"module\"` in `package.json`).","message":"Starting with version 3.0.0, `bpmn-js-differ` is distributed as an ES module (ESM) only. This means that `require()` statements for CommonJS environments will no longer work and must be replaced with `import` syntax.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Ensure you are using `bpmn-moddle` (preferably its latest major version, currently 10.0.0+) to parse your BPMN XML into definition objects before passing them to `diff`.","message":"Version 3.0.0 introduced a fundamental change by building the diffing logic on top of `bpmn-moddle`'s infrastructure. While the public `diff` function signature generally remained stable, this change mandates the use of `bpmn-moddle` (specifically version 9.0.0 or higher) to parse BPMN XML into the expected definition objects. Directly passing raw XML strings or objects from older parsing utilities will not work.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Upgrade to `bpmn-js-differ@3.0.1` or newer to ensure accurate detection of `$type` changes.","message":"Prior to version 3.0.1, `bpmn-js-differ` might not have reliably detected changes to an element's `$type` property. For example, changing a `bpmn:Task` to a `bpmn:ServiceTask` might have been missed or incorrectly reported.","severity":"gotcha","affected_versions":"<3.0.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change `const { diff } = require('bpmn-js-differ');` to `import { diff } from 'bpmn-js-differ';` and ensure your project is configured for ESM.","cause":"`bpmn-js-differ` v3.0.0+ is an ES module, but you are trying to `require()` it in a CommonJS context.","error":"ERR_REQUIRE_ESM"},{"fix":"Always parse your BPMN XML using `bpmn-moddle` (e.g., `bpmnModdle.fromXML(xml)`) and pass the resulting `rootElement` (definitions) to `diff`.","cause":"The `diff` function expects valid BPMN definition objects, typically produced by `bpmn-moddle`. This error often occurs when invalid inputs (e.g., `undefined`, raw XML strings, or incorrectly parsed objects) are provided.","error":"TypeError: Cannot read properties of undefined (reading 'length')"},{"fix":"Use a named import: `import { diff } from 'bpmn-js-differ';`.","cause":"You are attempting a default import (`import BpmnDiffer from 'bpmn-js-differ';`) but the library only provides named exports (specifically `diff`).","error":"SyntaxError: The requested module 'bpmn-js-differ' does not provide an export named 'default'"}],"ecosystem":"npm"}