npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bpmnkit/engine

v1.2.1

Published

Lightweight BPMN 2.0 process simulator for tests and demos in browsers and Node.js — zero dependencies

Readme

npm license typescript ai-assisted tier: core

Website · Documentation · GitHub · Changelog

Core tier. Semver at 1.0: nothing breaks without a major release. See product tiers.


Overview

@bpmnkit/engine simulates BPMN 2.0 process execution — for tests, demos and debugging, not for running production processes. Deploy a diagram, start instances, track active elements, evaluate DMN decisions, and step through execution — all without a Camunda cluster.

Perfect for: workflow testing, visual debugging, interactive demos, offline simulation, and process-driven UI flows.

Features

  • Gateways — exclusive (with default flow), parallel, inclusive, event-based; complex splits like inclusive
  • Variables — Zeebe-style scopes: input mappings are local to the element, results propagate to the nearest scope that defines them (else the process), output mappings pick what leaves an element
  • Events — timer (ISO 8601 duration/date/cycle), message (by name, optional correlation key), signal, error, escalation, link, compensation and terminate
  • Boundary events — timer, message, signal and escalation, interrupting or not; error; a job's throwError is caught like an error end event
  • Sub-processes — embedded sub-processes, transactions, and event sub-processes (message, timer, signal, error, escalation start)
  • Call activities — run a process deployed in the same engine as a child instance, with Zeebe variable propagation
  • Multi-instance — parallel and sequential, inputCollection / outputCollection, loopCardinality, completionCondition
  • AI agents — an ad-hoc sub-process with a job worker (the AI Agent Sub-process connector) runs its tools: the worker completes its job with an adHocSubProcess job result (activateElements, isCompletionConditionFulfilled), and each tool's result is collected into outputCollection
  • DMN decisions — inline decision table evaluation via @bpmnkit/feel
  • Job workers — register handlers for service and user tasks by job type
  • Step-by-step — beforeComplete hook pauses between elements for debugging UIs
  • Zero dependencies — browser + Node.js, no server required

Not executed

  • Ad-hoc sub-processes without a job worker, and a call activity whose process is not deployed in the same engine, complete without running anything (the latter emits an element:warning event).
  • Conditional events are not evaluated, a message start event of a top-level process does not start an instance, and transaction cancel events are not modelled.
  • Inclusive and complex joins do not wait for the other branches, and a complex gateway's activation condition is ignored.
  • Compensation handlers run one after another in reverse completion order, as BPMN specifies; Zeebe invokes them all at once. Compensation event sub-processes are not modelled.

For Zeebe semantics, @bpmnkit/engine/wasm-runner runs the same scenarios on the Reebe engine compiled to WebAssembly (experimental). See Conformance.

Installation

npm install @bpmnkit/engine

Quick Start

import { Engine } from "@bpmnkit/engine"

const engine = new Engine()

// Deploy a BPMN process
engine.deploy({ bpmn: xml })

// Register job workers
engine.registerJobWorker("payment-service", async (job) => {
  const result = await processPayment(job.variables)
  return { success: result.ok }
})

// Start an instance
const instance = engine.start("order-process", {
  orderId: "ORD-001",
  amount: 99.99,
})

// Track execution
instance.onChange((state) => {
  console.log("Active:", state.activeElements)
  console.log("Vars:", state.variables_snapshot)
})

Step-by-step execution

const steps: Array<() => void> = []

const instance = engine.start("my-process", {}, {
  beforeComplete: (elementId) =>
    new Promise((resolve) => {
      console.log("Paused at:", elementId)
      steps.push(resolve)  // advance by calling steps.pop()()
    }),
})

Testing processes in Vitest or Jest

@bpmnkit/engine/testing wraps the simulator in a test fixture — no Docker, no cluster: job and connector mocks, manual job completion, a virtual clock for timers, BPMN matchers and path coverage.

import "@bpmnkit/engine/testing/vitest" // registers the matchers (Jest: expect.extend(bpmnMatchers))
import { createProcessTest, formatCoverage } from "@bpmnkit/engine/testing"

const t = await createProcessTest({ bpmn: new URL("./order.bpmn", import.meta.url) })
t.mockJob("payment", { result: { paid: true } })
t.mockConnector("io.camunda:http-json:1", { response: { status: 200, body: {} } })

const run = await t.start("order-process", { amount: 10 })
await run.completeJob("ship", { shipped: true }) // unmocked jobs wait for you
await run.publishMessage("payment-confirmed")
await run.advanceTime("PT1H")                    // fires timers instantly

expect(run).toHaveCompleted()
expect(run).toHavePassed(["payment", "ship"])
expect(run).toHaveVariables({ paid: true })

console.log(formatCoverage(t.coverage()))        // flow nodes and sequence flows reached
t.dispose()

vitest is an optional peer dependency, needed only for the /testing/vitest entry. See Testing processes.

AI agents under deterministic tests

mockAiAgent plays the AI Agent connector from a script of turns: which tools the model calls, with which fromAi() arguments, then its answer. The tools run for real; unknown tools, wrong arguments and a script that runs out fail the run. Record a transcript to a JSON cassette once and replay it — no model, no network.

import { readAgentCassette } from "@bpmnkit/engine/testing"

const agent = t.mockAiAgent("support-agent", [
  { toolCalls: [{ name: "lookup-order", arguments: { orderId: "1042" } }] },
  { responseJson: { answer: "It ships tomorrow.", resolved: true } },
])
// or: t.mockAiAgent("support-agent", await readAgentCassette(new URL("./order.cassette.json", import.meta.url)))

const run = await t.start("support", { customerMessage: "Where is order 1042?" })
expect(agent).toHaveCalledTools([{ name: "lookup-order", arguments: { orderId: "1042" } }])
t.coverage().tools // which of the agent's tools the tests called

See Testing AI agents.

API Reference

Engine

| Method | Description | |--------|-------------| | deploy({ bpmn, forms?, decisions? }) | Register BPMN (+ optional DMN/form assets) | | start(processId, variables?, options?) | Start a new instance; returns ProcessInstance | | registerJobWorker(type, handler) | Handle service tasks with a given job type | | broadcastSignal(name, variables?) | Deliver a signal to every running instance; returns instances its signal start events started | | getDeployedProcesses() | List all deployed process IDs |

ProcessInstance

| Member | Description | |--------|-------------| | state | "running" \| "completed" \| "terminated" \| "failed" | | activeElements | IDs of currently active flow nodes | | variables_snapshot | Flat snapshot of current variable scope | | onChange(cb) | Subscribe to state changes | | cancel() | Terminate the instance | | deliverMessage(name, variables?, correlationKey?) | Correlate a message to the oldest waiting subscription; returns whether one received it | | deliverSignal(name, variables?) | Deliver a signal to this instance only | | beforeComplete? | Optional step hook (set after start()) |

Besides the element and variable events, onChange reports element:terminated when an interrupting event, a terminate end event or a completion condition cancels an element, and element:warning when the simulator skips something it cannot run.


Related Packages

| Package | Description | |---------|-------------| | @bpmnkit/core | BPMN/DMN/Form parser, builder, layout engine | | @bpmnkit/canvas | Zero-dependency SVG BPMN viewer | | @bpmnkit/editor | Full-featured interactive BPMN editor | | @bpmnkit/feel | FEEL expression language parser & evaluator | | @bpmnkit/plugins | 34 composable canvas plugins | | @bpmnkit/api | Camunda 8 REST API TypeScript client | | @bpmnkit/ascii | Render BPMN diagrams as Unicode ASCII art | | @bpmnkit/markdown | BPMN diagrams in Markdown — remark, markdown-it and README pre-rendering | | @bpmnkit/docspack | BPMN Kit docs as an offline docspack package for AI agents | | @bpmnkit/camunda-docspack | Camunda 8 docs as an offline docspack package for AI agents | | @bpmnkit/ui | Shared design tokens and UI components | | @bpmnkit/profiles | Shared auth, profile storage, and client factories for CLI & proxy | | @bpmnkit/operate | Monitoring & operations frontend for Camunda clusters | | @bpmnkit/connector-gen | Generate connector templates from OpenAPI specs | | @bpmnkit/connectors | Camunda 8 OOTB connector catalog and deterministic template application | | @bpmnkit/cli | Camunda 8 command-line interface (casen) | | @bpmnkit/proxy | Local AI bridge and Camunda API proxy server | | @bpmnkit/patterns | Domain process patterns for BPMNKit AIKit | | @bpmnkit/reebe-wasm | WebAssembly BPMN engine for browser simulation | | @bpmnkit/worker-client | Thin Zeebe REST client for standalone workers | | @bpmnkit/flow | Code-first durable flows that derive BPMN, job types and workers | | @bpmnkit/user-tasks | Embeddable user task widget for Camunda 8 | | @bpmnkit/cli-sdk | Plugin authoring SDK for the casen CLI | | @bpmnkit/create-casen-plugin | Scaffold a new casen CLI plugin in seconds | | @bpmnkit/casen-report | HTML reports from Camunda 8 incident and SLA data | | @bpmnkit/casen-worker-http | Example HTTP worker plugin — completes jobs with live JSONPlaceholder API data | | @bpmnkit/casen-worker-ai | AI task worker — classify, summarize, extract, and decide using Claude |

License

MIT © BPMN Kit — made by u11g