m8flow is an open-source workflow engine implemented in pure Python.
It is built on the proven foundation of SpiffWorkflow, with a vision shaped by 8 guiding principles for flow orchestration:
Merge flows effectively – streamline complex workflows
Make apps faster – speed up development and deployment
Manage processes better – bring structure and clarity to execution
Minimize errors – reduce mistakes through automation
Maximize efficiency – get more done with fewer resources
Model workflows visually – design with simplicity and clarity
Modernize systems – upgrade legacy processes seamlessly
Mobilize innovation – empower teams to build and experiment quickly
Future-proof alternative → replaces Camunda 7 with a modern, Python-based workflow engine
Enterprise-grade integrations → tight alignment with formsflow.ai, caseflow, and the SLED360 automation suite
Open and extensible → open source by default, extensible for enterprise-grade use cases
Principles-first branding → “m8” = 8 principles for flow, consistent with the product family (caseflow, formsflow.ai)
Visual and symbolic meaning:
- “8 nodes” in automation
- “8” resembles a curled Python → Python-native identity
- “m8” → mate / mighty → collaboration and strength
BPMN 2.0: pools, lanes, multi-instance tasks, sub-processes, timers, signals, messages, boundary events, loops
DMN: baseline implementation integrated with the Python execution engine
Forms support: extract form definitions (Camunda XML extensions → JSON) for CLI or web UI generation
Python-native workflows: run workflows via Python code or JSON structures
Integration-ready: designed to plug into formsflow, caseflow, decision engines, and enterprise observability tools
A complete list of the latest features is available in our release notes.
This document describes how to run M8Flow locally for testing and development purposes using Docker for infrastructure.
Ensure the following tools are installed:
- Git
- Docker and Docker Compose
The project repository:
https://github.com/AOT-Technologies/m8flow
Clone the repository and move into the project directory:
git clone https://github.com/AOT-Technologies/m8flow.git
cd m8flowA sample environment file is provided at the repository root. Create a working environment file:
cp sample.env .envEdit the .env file if adjustments are required for the local setup.
For reliable networking between browser, Docker containers, and local services, use the machine's LAN IP address instead of localhost.
Example:
192.168.1.105
This IP address will be used in Keycloak configuration and when accessing frontend and backend services.
Start all required infrastructure services (databases, Keycloak, MinIO, etc.) and init containers (important for the first time):
docker-compose --profile init -f docker/m8flow-docker-compose.yml up -d --buildIf the init containers are not needed:
docker-compose -f docker/m8flow-docker-compose.yml up -d --buildTo stop containers and remove associated volumes (this deletes local database data):
docker compose -f docker/m8flow-docker-compose.yml down -vAlternatively you can run the commands below to start M8Flow docker containers:
Linux:
git clone https://github.com/AOT-Technologies/m8flow.git
cd m8flow
cp sample.env .env
IP="$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}')" && \
[ -n "$IP" ] && grep -q "<LOCAL_IP>" .env && sed -i.bak "s/<LOCAL_IP>/$IP/g" .env && echo "Using IP=$IP"
docker-compose --profile init -f docker/m8flow-docker-compose.yml up -d --build
Windows CMD:
git clone https://github.com/AOT-Technologies/m8flow.git
cd m8flow
copy sample.env .env
powershell -NoProfile -Command "$ifIndex=(Get-NetRoute '0.0.0.0/0' | sort RouteMetric,InterfaceMetric | select -First 1).IfIndex; $ip=(Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $ifIndex | ?{ $_.IPAddress -notlike '169.254*' -and $_.IPAddress -notlike '127.*' } | select -First 1 -Expand IPAddress); $c=Get-Content .env -Raw; $n=$c -replace '<LOCAL_IP>', $ip; if($n -eq $c){ throw 'No <LOCAL_IP> tokens found in .env' }; $n | Set-Content .env -Encoding UTF8; Write-Host Using IP=$ip"
docker-compose --profile init -f docker/m8flow-docker-compose.yml up -d --build
After the containers start, continue below to the Keycloak Setup to import the realm and configure the client.
In the Keycloak Admin Console http://localhost:7002/ log in using the configured administrator credentials.
Click on "Keycloak master" and then on "Create a realm".
Browse or copy the content of m8flow/spiffworkflow-backend/keycloak/realm_exports/spiffworkflow-basic-realm.json and click on "Create".
With the realm "spiffworkflow" selected, click on "Clients" and then on the client ID spiffworkflow-backend.
Set the following:
Valid redirect URIs
http://<LOCAL_IP>:8000/*
http://<LOCAL_IP>:8001/*
Valid post logout redirect URIs
http://<LOCAL_IP>:8000/*
http://<LOCAL_IP>:8001/*
Disable Client authentication.
Create a virtual environment and activate it:
python -m venv .venv
source .venv/bin/activateInstall uv and all the dependencies:
pip install --upgrade pip && pip install uv
cd spiffworkflow-backend
uv sync --all-groups --active
cd ..To have the backend running locally, on the root of the project, run:
./extensions/m8flow-backend/bin/run_m8flow_backend.sh
You can test it running:
curl http://localhost:8000/v1.0/status
The result should be:
{
"ok": true,
"can_access_frontend": true
}Running all tests:
pytest -c spiffworkflow-backend/pyproject.toml ./extensions/m8flow-backend/tests/ -q
Running a specific test:
pytest -c spiffworkflow-backend/pyproject.toml ./extensions/m8flow-backend/tests/unit/m8flow_backend/services/test_tenant_context_middleware.py -q
Open http://<LOCAL_IP>:8001/ on your browser and you are going to be redirected to keycloak authentication. Now enter temporary credentials: user admin password admin.
Now you can user M8Flow:
---We welcome contributions from the community!
- Submit PRs with passing tests and clear references to issues
m8flow builds upon the outstanding work of the SpiffWorkflow community and contributors over the past decade. We extend gratitude to:
- Samuel Abels (@knipknap), Matthew Hampton (@matthewhampton)
- The University of Virginia & early BPMN/DMN contributors
- The BPMN.js team, Bruce Silver, and the wider open-source workflow community
- Countless contributors past and present
m8flow is released under the GNU Lesser General Public License (LGPL).







