Skip to content

Contributor Guide

Prerequisites

  • Node.js v20 or later
  • corepack enabled: corepack enable
  • VS Code

The webview dev:* scripts (standalone browser preview) use portless, which is installed automatically as a dev dependency by yarn install — no global install required.

Setup

bash
yarn install

Project Structure

This is a Yarn 4 workspace monorepo containing a single VS Code extension (Camunda Modeler) and its supporting packages:

WorkspacePathDescription
vs-code-bpmn-modelerapps/modeler-pluginVS Code extension host (Node/Webpack)
@miragon/bpmn-modeler-webviewapps/bpmn-webviewBPMN editor UI (Vite/browser)
@miragon/dmn-modeler-webviewapps/dmn-webviewDMN editor UI (Vite/browser)
@miragon/bpmn-modeler-sharedlibs/sharedShared message types and utilities

Workspace dependencies

Every workspace declares its own runtime and build dependencies in its own package.json. The root package.json only carries cross-cutting tooling (eslint, prettier, npm-run-all, typescript). This lets CI install just the tree it needs via yarn workspaces focus:

bash
# Modeler-only tree (no Theia, no native-keymap, no apt-step required)
yarn workspaces focus bpmn-modeler vs-code-bpmn-modeler @miragon/bpmn-modeler-webview \
  @miragon/dmn-modeler-webview @miragon/bpmn-modeler-deployment-webview @miragon/bpmn-modeler-shared @miragon/bpmn-modeler-append-menu \
  @miragon/bpmn-modeler-clipboard @miragon/bpmn-modeler-i18n \
  @miragon/bpmn-modeler-element-template-chooser \
  @miragon/create-append-c7-element-templates

# Just the c7 npm lib
yarn workspaces focus bpmn-modeler @miragon/create-append-c7-element-templates

# Just the docs site
yarn workspaces focus bpmn-modeler docs

# Full repo (needed for the standalone Theia app)
yarn install

The standalone app (apps/standalone) pulls Theia + native-keymap, whose node-gyp postinstall needs libx11-dev libxkbfile-dev libsecret-1-dev on Linux — which is why only the full-install workflow (build.yml) runs the apt-step.

Development Workflow

Build

bash
# Build everything (libs → webviews + plugin in parallel)
yarn build

# Build only the shared libraries
yarn build:libs

Watch mode

bash
# Rebuild all workspaces on change (feeds the F5 Extension Host)
yarn watch

Docs site

bash
yarn docs:dev

Opens the VitePress docs site in your browser.

Run the extension in VS Code

  1. Open the repository root in VS Code.
  2. Run yarn watch to start watch mode.
  3. Open the Run and Debug panel and select "Run modeler-plugin".
  4. Press F5 to launch the Extension Development Host.

To reload the extension host after a change, press Cmd+R (macOS) or Ctrl+R ( Windows/Linux).

Target a single workspace

bash
yarn workspace vs-code-bpmn-modeler build
yarn workspace @miragon/bpmn-modeler-webview build

Preview the BPMN webview in a plain browser

The BPMN webview can run standalone against a mocked VS Code host. This avoids reloading the Extension Development Host while iterating on webview UI.

bash
yarn dev:bpmn-webview

This launches a Vite dev server via portless; the URL is printed to stdout when the server starts.

A URL query parameter selects what the mock serves:

URLWhat renders
/ (or ?mode=modeler)Full editable Camunda modeler with a hardcoded sample diagram — matches the production modeler experience.
/?mode=diff-beforeReadonly before (left) pane of a diff view, with highlights for removed / changed / moved elements.
/?mode=diff-afterReadonly after (right) pane, with highlights for added / changed / moved elements.

The diff modes run bpmn-js-differ against two fixture XMLs (apps/bpmn-webview/src/app/__fixtures__/mock-diff.ts) so highlights reflect the real differ's output. All mock code and its dependencies are gated on NODE_ENV === "development" and tree-shaken out of the production webview bundle.

Testing & Linting

bash
# Run all tests (includes coverage by default)
yarn test

# Run a single test file
yarn test --testPathPattern=apps/modeler-plugin/src/service/bpmnUtils.spec.ts

# Lint
yarn lint

Coverage reports are uploaded to Codecov on CI.

Code Style

ToolConfigurationKey rules
EditorConfig.editorconfig4-space indent, LF line endings, max 89 chars
Prettier.prettierrcDouble quotes, trailing commas, arrow parens always
ESLinteslint.config.mjsTypeScript strict

Prettier and ESLint are enforced by the lint step in CI.

Branching & Commits

Branching model

Commit messages

Use semantic commit messages scoped to the affected workspace:

feat(bpmn): add token simulation toolbar
fix(dmn): correct decision table rendering
chore(shared): update message type definitions

Common types: feat, fix, refactor, chore, docs, test.

CI/CD

WorkflowTriggerPurpose
Buildevery push / PRlint → test → build, full install (apt-step for Theia native modules)
PR LabelerPR opened / updatedauto-labels PRs by changed workspace
**Prepare Release ***manual (workflow_dispatch)bump version, sanity build, commit, tag, create GitHub Release
**Publish ***release: published (or workflow_dispatch + dry-run)build artefact, attach to release, push to Marketplace / npm / GitHub Release
Deploy Docsrelease: published / manualVitePress build + GitHub Pages deploy

There are three prepare-* and three publish-* workflows — one pair per artefact (VS Code extension, c7 npm lib, standalone macOS app). See Release process for the operational guide and the pipeline flow diagram.

Architecture Overview

The extension uses a flat service architecture with plain constructor wiring — no DI framework.

apps/modeler-plugin/src/
  domain/         # Pure domain types — no external dependencies
  infrastructure/ # VS Code API adapters (EditorStore, VsCodeDocument, …)
  service/        # Business logic (BpmnModelerService, ArtifactService, …)
  controller/     # VS Code events → service calls
  main.ts         # Wiring: EditorStore → VsCode* → Services → Controllers

Key design decisions:

  • Echo prevention: each open editor gets a ModelerSession guard that blocks the onDidChangeTextDocument echo caused by the extension's own document write.
  • Element template discovery: convention-based — no project config file needed. Templates are resolved under <configFolder>/element-templates/ walking up from the BPMN file to the workspace root.
  • Webview communication: postMessage with typed message contracts defined in libs/shared.

See CLAUDE.md in the repository root for the full architectural reference.