bpmn-engine: a BPMN 2.0 execution engine for Node
BPMN 2.0 execution engine. Open source javascript workflow engine.
At a glance
- What is it?
- bpmn-engine runs BPMN 2.0 process definitions as JavaScript. It is deliberately small, it declares its runtime dependencies as peer dependencies so you pin and share one copy, and it separates the element behaviour into its own package, which is what makes it possible to extend the engine to schemas BPMN never covered.
- Who is it for?
- bpmn-engine suits a Node application that already has BPMN diagrams and needs to run them, especially one that also has non-BPMN process definitions, since the element layer is pluggable. It is a poor fit if you want a workflow engine with a designer, a dashboard and a human task inbox, because this is the execution half and nothing else, and a poor fit if you cannot accept a dependency set you have to manage yourself.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The execution half, and nothing else
The description is two sentences and they set the scope exactly.
It is a BPMN 2.0 execution engine, an open source JavaScript workflow engine. The readme's first line is the same, and the project carries a status badge describing it as active, having reached a stable, usable state and being actively developed.
So this is the part of a workflow system that takes a diagram and runs it, and it is worth being clear about what that leaves out. There is no diagram editor, no task inbox, no administration console and no reporting. The visual modeler is somebody else's job, and the readme says so by pointing at the Camunda modeler for the diagrams in its own documentation.
What you get in exchange is a runtime that executes the process semantics, and the elements involved are the interesting part. A BPMN diagram is mostly a picture, but the runtime has to make decisions: whether a gateway passes, which branch a conditional flow takes, what a timer waits for, how a parallel path joins, and what a script task actually runs. An engine that implements those is doing real work, and doing it in JavaScript means the process runs inside the same application, the same process, and the same deployment as the rest of your code.
The documentation is organised into an API reference, a set of examples, an upgrade guide, a note comparing two major versions of the parser, and a changelog. That is the documentation set you would expect from a library whose users are integrating it into something, not experimenting with it.
Peer dependencies, and the deliberate version span
The dependency decision is unusual and worth understanding, because it changes who is responsible for what.
The runtime dependencies are declared as peer dependencies, so you install and pin them yourself and the engine reuses your single copy. The install is one command:
npm install bpmn-engine bpmn-elements bpmn-moddle moddle-context-serializer debug smqpThe table that follows names the role of each one. The elements package holds the element behaviour functions. The parser package is the BPMN XML parser. The context serializer is for a persistable source context, which is how a running process survives a restart. The message broker is what drives execution, and the logging library is the familiar one.
The reason to make these peers rather than dependencies is version control of the parts that matter. When a library pins its own copy of a parser, two libraries in the same application end up with two parsers, and objects created by one cannot be read by the other. Here there is one copy of everything, and the application decides which version to use.
The one entry with a warning is the parser, which spans a major version on purpose. The documentation explains that there was an import change between the two major versions and that the persisted state stays compatible across the upgrade. That is a strong claim, and the fact that the project bothers to document it separately suggests it is true, because persisted process state is exactly the thing that breaks silently in a workflow engine: the process does not fail, it resumes with the wrong history.
Extending beyond BPMN, and the extensions that already exist
The supported elements section is short and the scope is deliberate.
The engine only supports the elements and attributes included in the BPMN 2.0 scheme, and the aim is at least to have core support. The detailed list lives in the separate elements package, and the readme points there for the full set.
The extension mechanism is the interesting part, and it is what makes the project more than a BPMN reader. The engine can be extended to understand other schemas and elements, and the documentation, guides and ready-made extensions for the stack are published on the author's own site, with the readme's advice being to check there before writing a new extension from scratch.
Two extensions are named, and the fact that they come from two different authors and two different organisations is the point. The extensions are published under a scoped package name, and the first is from the author of the engine itself while the second comes from a company that uses it. That is a small ecosystem already, which is the best possible evidence for the claim that the extension point is usable.
For a team whose processes are drawn in plain BPMN, none of this matters. For a team whose real process definitions live in a vendor format with vendor elements, it is the feature that decides whether the engine is usable at all, and the answer is that it is extensible and two people have already done it.
Debugging a workflow at run time
Debugging a workflow engine is a specific problem, because the interesting behaviour happens over time, inside a broker, with state spread across steps. The readme's debugging section is short and directly aimed at that.
The package ships with the logging library activated through an environment variable, and you can also provide your own logger. The simplest invocation selects everything under the engine:
DEBUG=bpmn-engine:*More granular debugging is done by filtering on the element type, which is the useful part, because a process that misbehaves usually misbehaves in one kind of step:
DEBUG=*scripttask*,*:error:*The Windows PowerShell equivalents are given too, since the environment variable syntax differs, and the readme even shows how to switch it off again by setting the variable to an empty string. That last detail is the sort of thing that only gets written down after somebody has been annoyed by it.
The choice of the logging library is also the one every Node developer already knows, which means the output lands in whatever you already use to read logs, and the namespace convention means a filter of the shape given above is enough to isolate one step type from a noisy process.
The scripts tell you how the project is tested
The package manifest is worth reading, because the scripts describe a testing setup that is more thorough than most libraries of this size have.
The test command runs the test runner in parallel, and the post-test chain is the interesting part. After the tests pass, it runs the linting, then a table of contents generation step, then the distribution build, and finally a step that tests the documentation.
That last step is the notable one. There is a script that runs the code examples embedded in the API, examples and upgrade documents and checks them, with a configuration file for the test runner. So the examples in the documentation are executed as part of the test run, and a snippet that stops working fails the build.
The rest of the tooling follows the same pattern of checking the artefacts rather than only the code. The table of contents step regenerates the contents blocks in the readme and the three documents, and a diff in the repository is a broken build. The distribution build is a bundler run, and the packaging step runs it first, so a published tarball is always built from a clean state. Coverage is produced in three formats, HTML, text and lcov, through a coverage tool.
The repository layout matches a project that keeps its sources and its published output separate, with a source directory, a build directory and a types directory, and the package manifest points the module entry at the source and the main entry at the built commonjs file. The type declarations are generated, and the package is marked as having no side effects, so a bundler can drop what is not used.
The project state and the shape of the version numbers
Two things are worth noting about the release and the versioning.
The repository has no GitHub releases, so there is no tag list to consult, but the package version is 26.0.5, and the last push was on 2026-10-14 with the repository not archived. A version number in the twenties with a patch component and no tags means the version tracks something other than a chronological release train, most likely a year and a count, which is a sensible scheme for a library where the BPMN element set itself changes.
The build badges show continuous integration on Linux and on Windows separately, and a coverage badge, and the status badge describes the project as active and stable. The engine requires Node 18 or newer, and the repository carries a Node version file and a Mocha configuration.
There is also an agent instructions file at the root and a changelog, and the documentation is split across the API reference, the examples, the upgrade guide and the parser comparison, with the upgrade guide being the one to read if you are moving a system that persists its process state.
The acknowledgements close the readme with the parser project the engine is built upon and the modeler used for the diagrams, which is a good description of the dependency chain in two lines: a JavaScript engine, a BPMN XML parser, and a desktop diagram editor, with the execution engine in the middle.
Editorial conclusion
bpmn-engine suits a Node application that already has BPMN diagrams and needs to run them, especially one that also has non-BPMN process definitions, since the element layer is pluggable. It is a poor fit if you want a workflow engine with a designer, a dashboard and a human task inbox, because this is the execution half and nothing else, and a poor fit if you cannot accept a dependency set you have to manage yourself. Before you commit, read the note on the major version span of the parser, because persisted process state has to stay compatible across that upgrade, and check the supported elements list against the diagrams you actually have.
Frequently asked questions
What is bpmn-engine?
A BPMN 2.0 execution engine, an open source JavaScript workflow engine that runs process definitions inside your Node application. It supports the elements and attributes in the BPMN 2.0 scheme, with the aim of at least core support, and it can be extended to understand other schemas.
Why are the dependencies peer dependencies?
So that you install and pin them yourself and the engine reuses your single copy, rather than the engine shipping its own and the application ending up with two parsers whose objects cannot be exchanged. The install is a single command that names the engine and the five peers, including the BPMN XML parser, the element behaviour package, the context serializer, the message broker and the logger.
How do I debug a running bpmn-engine process?
The package ships with the logging library enabled through an environment variable, and you can supply your own logger. You can select everything under the engine with a namespace filter, or filter on the element type for a finer breakdown, and the readme gives the PowerShell equivalents for setting and clearing the variable.
Can bpmn-engine run process definitions that are not BPMN?
The engine can be extended to understand other schemas and elements, and the readme points to a site publishing documentation, guides and ready-made extensions for the stack, listing two of them. The supported elements for plain BPMN are documented in the separate elements package.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/paed01-bpmn-engine)Was this useful?