This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
bpmn-visualization is a TypeScript library for visualizing process execution data on BPMN diagrams. It parses BPMN 2.0 XML, builds an internal model, and renders interactive diagrams using mxGraph with extensive customization capabilities.
npm install # Install dependencies
npm run dev # Start dev server at http://localhost:10001/dev/public/index.html
npm run all # Full check: clean, lint, build, test (run before PRs)npm run build # TypeScript compilation check (no output)
npm run build-bundles # Create distribution bundles (ESM, IIFE)
npm run prepack # Full build: generate types + bundles (runs before npm pack)npm test # Run all tests (unit + integration + e2e)
npm run test:unit # Jest unit tests (parsers, converters, utilities)
npm run test:unit:coverage # Unit tests with coverage
npm run test:unit:watch # Watch mode for unit tests
npm run test:integration # Integration tests (parser → renderer)
npm run test:e2e # Playwright E2E with visual regression
npm run test:e2e:verbose # E2E tests with debug output
npm run test:perf # Performance benchmarks
npm run test:bundles # Validate distribution bundlesTo run a single test file:
# Unit test
npx jest test/unit/path/to/test-file.test.ts --config=./test/unit/jest.config.cjs
# Integration test
npx jest test/integration/path/to/test-file.test.ts --config=./test/integration/jest.config.cjs
# E2E test
npx jest test/e2e/path/to/test-file.test.ts --config=./test/e2e/jest.config.cjsnpm run lint # Auto-fix linting issues
npm run lint-check # Check linting without fixingWhen writing or updating code, follow these JSDoc practices:
Public API Documentation:
- REQUIRED: All public classes, methods, interfaces, and types must have JSDoc comments
- REQUIRED: All new public API elements must include the
@sincetag with the version number- Infer the next version from
package.json(current:0.47.0-post→ next:0.48.0) - Always confirm the target version with the user once per session before using it
- Infer the next version from
- Include description,
@paramfor parameters,@returnfor return values - Document exceptions with
@throwswhen applicable - Use
@examplefor complex APIs to show usage patterns - Mark experimental APIs with
@experimentaltag - Mark deprecated APIs with
@deprecatedand provide migration guidance
Internal Code Documentation:
- OPTIONAL: Internal/private code may have JSDoc but it's not required
- Prefer self-documenting code with clear naming over excessive comments
- Add JSDoc for complex internal logic where the "why" isn't obvious
- Use inline comments for non-trivial implementation details
JSDoc Best Practices:
- Keep descriptions concise but complete
- Use TypeScript types; avoid redundant type information in JSDoc (rely on
@param {Type}when TypeScript inference isn't sufficient) - Link to related types/methods using
{@link ClassName}or{@link methodName} - Document parameter constraints and valid ranges
- Specify units for numeric parameters (e.g., "duration in milliseconds")
Example:
/**
* Loads and renders a BPMN diagram from XML.
*
* @param xml The BPMN 2.0 XML content to parse and render
* @param options Optional configuration for rendering behavior
* @returns The loaded model information
* @throws {Error} If the XML is invalid or cannot be parsed
* @since 0.48.0
* @example
* const bpmnVisualization = new BpmnVisualization({ container: 'diagram' });
* bpmnVisualization.load('<definitions>...</definitions>');
*/
public load(xml: string, options?: LoadOptions): LoadResult {
// implementation
}npm run docs # Generate all documentation
npm run docs:user # Generate user documentation
npm run docs:api # Generate API documentation with typedocThe library follows a 3-layer pipeline architecture with clear separation of concerns:
BpmnVisualization.load(xml)
├─ 1. Parse: XML → BpmnModel (internal representation)
├─ 2. Register: BpmnModel → RenderedModel (prepare for rendering)
└─ 3. Render: RenderedModel → mxGraph cells (visual display)
Two-stage parsing:
- Stage 1:
BpmnXmlParserconverts BPMN XML to JSON usingfast-xml-parser - Stage 2:
BpmnJsonParserorchestrates converters to buildBpmnModel
Key Converters (in src/component/parser/json/converter/):
ProcessConverter- Activities, events, gateways, sequence flowsCollaborationConverter- Pools, lanes, message flowsDiagramConverter- Visual information (shapes, edges, bounds, labels)EventDefinitionConverter- Event definitions (timer, message, error, etc.)
Critical Pattern: Converters populate a shared ConvertedElements registry during semantic parsing, then DiagramConverter links visual bounds/waypoints to semantic elements.
Core types:
BpmnModel- Top-level container (pools, lanes, flowNodes, edges)Shape- CombinesShapeBpmnElement(semantic) +Bounds(visual) +LabelEdge- CombinesEdgeBpmnElement(semantic) + waypoints (visual) +LabelShapeBpmnElementhierarchy - Rich type system with markers, event definitions, subprocess kinds
Important: The model is mxGraph-independent - pure domain model of BPMN.
Initialization chain:
GraphConfigurator
├─ Creates BpmnGraph (extends mxGraph)
├─ StyleConfigurator.configureStyles()
├─ registerShapes() - Custom mxShape implementations
└─ registerEdgeMarkers() - Custom edge markers
BpmnRenderer:
- Converts
RenderedModelto mxGraph cells viainsertVertex()/insertEdge() - Uses
StyleComputerto generate mxGraph style strings - Uses
CoordinatesTranslatorfor coordinate transformations (BPMN uses absolute coords, mxGraph uses relative-to-parent) - Inserts in order: pools → lanes → subprocesses → flow nodes → boundary events → edges
Custom Shapes (src/component/mxgraph/shape/):
- Each BPMN element has custom
mxShapesubclass (EventShape, TaskShape, GatewayShape) IconPainterrenders BPMN-specific icons (event definitions, task markers)BpmnCanvasextends mxGraph canvas with BPMN primitives
BpmnElementsRegistry provides the public API, aggregating:
BpmnModelRegistry- Semantic model access viagetBpmnSemantic(id)HtmlElementRegistry- Query DOM elements by ID or kindStyleRegistry- Update mxGraph cell styles dynamicallyCssClassesRegistry- Manage CSS classes on DOM elementsOverlaysRegistry- Add/remove overlays on elements
Key insight: Bridges semantic model with rendered DOM/mxGraph, enabling runtime manipulation without re-parsing.
Multi-layer approach:
- Unit (
test/unit/) - Jest with jsdom, tests parsers/converters in isolation - Integration (
test/integration/) - Tests parser → renderer with real BPMN files - E2E (
test/e2e/) - Playwright visual regression with image snapshots - Performance (
test/performance/) - Load/render benchmarks - Bundles (
test/bundles/) - Validates ESM/IIFE distributions
E2E Pattern: Heavy use of image snapshots (in __image_snapshots__/) to verify visual rendering correctness across features.
Multiple specialized converters (ProcessConverter, DiagramConverter) each handle BPMN subdomains, all populating a shared ConvertedElements registry. This allows semantic and visual information to be processed separately then linked.
CoordinatesTranslator is critical because:
- BPMN XML uses absolute coordinates
- mxGraph uses relative-to-parent coordinates
- Parent-child relationships (pools → lanes → flow nodes) require careful coordinate conversion
- Labels have special offset calculations
Rendering order matters:
- Parents must be rendered before children
- Order: pools → lanes → subprocesses → flow nodes → boundary events → edges
- Managed through
parentIdreferences in the model
mxGraph is an implementation detail - fully wrapped by BpmnElementsRegistry. Public API never exposes mxGraph types (except experimental graph property). This enables potential future replacement.
- Add enum value to
ShapeBpmnElementKindinsrc/model/bpmn/internal/shape/kinds.ts - Extend model - Add class in
ShapeBpmnElement.tsif new semantic properties needed - Update converter - Add parsing logic in
ProcessConverteror relevant converter - Create shape class - Extend
mxShapeinsrc/component/mxgraph/shape/ - Register shape - Add to
registerShapes()inregister-style-definitions.ts - Add styles - Configure in
StyleConfigurator.ts - Add tests - Unit (parser), integration (parse→render), E2E (visual)
Trace how a BPMN task flows through the system:
- BPMN XML
<task>→BpmnXmlParser→ JSON object - JSON →
ProcessConverter.parseTask()→ createsShapeBpmnElement - Stored in
ConvertedElementsregistry DiagramConverterfinds matching<BPMNShape>→ createsShape(semantic + visual)BpmnRenderer.insertShape()→graph.insertVertex()with computed styleBpmnElementsRegistryenables runtime access via ID or kind lookup
- Node.js: Version in
.nvmrcfile (runnvm useif using nvm) - npm: Version associated with Node.js version
- Supported OS: Windows, Linux, macOS
The project uses Husky for pre-commit linting. If using a Node Version Manager and getting "Command not found" errors, create ~/.config/husky/init.sh with:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"- External contributions only accepted for issues marked "PR Accepted"
- Run
npm run allbefore opening PR (builds, checks, tests everything) - PR title becomes the commit message (commits are squashed)
- First PR requires signing the Contributor License Agreement