A full-stack, visual workflow automation engine built with Node.js, React Flow, PostgreSQL, and Redis. Design pipelines on a drag-and-drop canvas, then execute them through a distributed Bull queue with sandboxed JavaScript and Python runtimes.
- Visual editor β React Flow canvas with custom nodes, drag-and-drop, and live config panels.
- Distributed execution β Express API enqueues jobs to Redis (Bull); a separate worker process consumes and runs them.
- Sandboxed runtimes β JavaScript transformer nodes run inside Node's native
vmmodule; Python nodes execute in an isolated container. - Persistent state β Workflows, executions, users, and audit logs are stored in PostgreSQL via Knex migrations and repositories.
- Real-time updates β WebSocket channel streams execution status and logs to the UI.
- Auth & hardening β JWT auth, bcrypt password hashing, Helmet, CORS, and
express-rate-limit. - Node types β HTTP request, PostgreSQL query (parameterized), JavaScript transformer, Python script, and conditional branching.
graph LR
UI[React + Vite SPA] -->|REST + WS| API[Express API]
API --> DB[(PostgreSQL)]
API --> Q[(Redis / Bull)]
Q --> W[Bull Worker]
W --> JS[JS vm Sandbox]
W --> PY[Python Executor]
W --> DB
- Frontend (
frontend/) β Vite + React 18 + React Flow + Tailwind, talking to the backend via Axios and WebSockets. - Backend API (
backend/src/) β Express app exposing REST routes, WebSocket gateway, and queueing jobs to Bull. - Worker (
backend/src/queue/worker.js) β Out-of-process Bull consumer that runs node implementations. - Python executor (
python-executor/) β Container hosting the Python runtime used by Python nodes.
.
βββ backend/
β βββ src/
β β βββ api/ # routes, controllers, websocket
β β βββ core/ # engine, executor, scheduler
β β βββ db/ # knex migrations + repositories
β β βββ middleware/ # security, errorHandler
β β βββ nodes/ # http, database, python, transformer, conditional
β β βββ queue/worker.js # Bull worker entry point
β β βββ services/ # authService
β β βββ index.js # API entry point
β βββ knexfile.js
β βββ Dockerfile
βββ frontend/
β βββ src/
β β βββ components/ # CustomNode, ConfigModal, LoginModal
β β βββ services/api.js # Axios client
β β βββ App.jsx
β βββ Dockerfile
βββ python-executor/
β βββ Dockerfile
β βββ requirements.txt
βββ database/init.sql
βββ docker-compose.yml
docker-compose up -d --buildServices and ports:
| Service | URL / Port |
|---|---|
| Frontend (Vite) | http://localhost:3001 |
| Backend API | http://localhost:3002 |
| PostgreSQL | localhost:5432 (workflow_user / workflow_pass, db workflow_engine) |
| Redis | localhost:6379 |
Default login (seeded via database/init.sql / backend/reset_admin.js):
- Username:
admin - Password:
admin123
Change
JWT_SECRET, DB credentials, and the admin password before deploying anywhere non-local.
You'll need Node.js β₯ 18, PostgreSQL, and Redis running locally.
# 1. Backend API
cd backend
npm install
npm run migrate
npm run dev # starts API on PORT (default 3002)
# 2. Bull worker (separate terminal)
cd backend
npm run worker
# 3. Frontend
cd frontend
npm install
npm run dev # Vite dev server on 3001Environment variables used by the backend (see docker-compose.yml for defaults):
PORTβ API port (default3002)DATABASE_URLβ Postgres connection stringREDIS_HOST,REDIS_PORTJWT_SECRETFRONTEND_URLβ used for CORS
Backend (backend/package.json):
npm run devβ start API with nodemonnpm run workerβ start the Bull workernpm run migrate/migrate:rollbackβ Knex migrationsnpm testβ Jest testsnpm run lint/format
Frontend (frontend/package.json):
npm run devβ Vite dev servernpm run buildβ production buildnpm run previewβ preview built bundle
| Node | What it does |
|---|---|
| HTTP | Issues an HTTP request via Axios and returns the response. |
| Database | Runs a parameterized SQL query against PostgreSQL. |
| Transformer | Executes user JS inside a sandboxed vm context. |
| Python | Runs a script in the Python executor container. |
| Conditional | Branches based on a predicate evaluated against node input. |
Implementations live in backend/src/nodes.
MIT β see LICENSE.