A lightweight, self-hosted workflow automation platform inspired by n8n.
Build, execute, and monitor multi-step automation workflows through an interactive visual canvas — with real-time execution tracking powered by Server-Sent Events.
⚠️ Note: This is a prototype built for learning purposes. Only 1-2 node integrations (e.g., Gmail IMAP reader) are functional. The focus of this project is on demonstrating the architecture — not production-ready automation.
- Overview
- Architecture
- Tech Stack
- Features
- Getting Started
- Project Structure
- Screenshots
- How It Works
- License
Mini-n8n is a full-stack workflow automation platform that allows users to visually design automation pipelines using a drag-and-drop node editor and execute them with real-time feedback. It demonstrates how modern event-driven architectures work — combining a REST API, a message broker, background workers, and live streaming to deliver a seamless automation experience.
What can you do with it?
- 🎨 Design — Build workflows visually using a node-based canvas powered by XYFlow (React Flow)
- ⚙️ Configure — Set credentials and parameters for each node through a sleek configuration modal
- 🚀 Execute — Trigger workflows that are processed asynchronously via RabbitMQ workers
- 📡 Monitor — Watch execution unfold live with real-time node status updates via SSE (Server-Sent Events)
- 🔍 Inspect — Click any executed node to view its logs, input config, output data, and errors
graph TB
subgraph Client["🖥 Frontend (React + Vite)"]
UI["Visual Workflow Builder<br/>(XYFlow Canvas)"]
RD["Run Detail Dashboard<br/>(Real-time SSE Listener)"]
end
subgraph API["⚡ Backend (FastAPI)"]
REST["REST API Endpoints"]
SSE["SSE Stream Endpoint<br/>GET /run/{id}"]
end
subgraph Queue["📨 Message Broker"]
RMQ["RabbitMQ<br/>(workflow_tasks queue)"]
end
subgraph Worker["🔧 Worker Service"]
EX["Workflow Executor"]
REG["Component Registry"]
IMAP["Gmail IMAP Reader"]
TRIG["Trigger Handler"]
LOG["Logger Handler"]
end
subgraph DB["💾 Database"]
SQLite["SQLite<br/>(Shared Volume)"]
end
UI -- "POST /workflow" --> REST
UI -- "POST /run/{workflow_id}" --> REST
REST -- "Publish task" --> RMQ
RMQ -- "Consume task" --> EX
EX --> REG
REG --> IMAP
REG --> TRIG
REG --> LOG
EX -- "Write Run + NodeRun" --> SQLite
REST -- "Read/Write" --> SQLite
SSE -- "Poll latest state" --> SQLite
RD -- "EventSource connection" --> SSE
style Client fill:#1e293b,stroke:#3b82f6,color:#fff
style API fill:#1e293b,stroke:#22c55e,color:#fff
style Queue fill:#1e293b,stroke:#f59e0b,color:#fff
style Worker fill:#1e293b,stroke:#a855f7,color:#fff
style DB fill:#1e293b,stroke:#ef4444,color:#fff
sequenceDiagram
participant User
participant Frontend
participant Backend
participant RabbitMQ
participant Worker
participant Database
User->>Frontend: Click "Execute" on workflow
Frontend->>Backend: POST /api/v1/run/{workflow_id}
Backend->>Database: Create Run (status: PENDING)
Backend->>RabbitMQ: Publish {run_id} to workflow_tasks
Backend-->>Frontend: Return {run_id}
Frontend->>Frontend: Navigate to /run/{run_id}
Frontend->>Backend: EventSource → GET /api/v1/run/{run_id}
RabbitMQ->>Worker: Deliver task
Worker->>Database: Update Run → RUNNING
loop For Each Node
Worker->>Database: Create NodeRun (RUNNING)
Note over Backend,Frontend: SSE pushes update → node turns blue
Worker->>Worker: Execute node handler
Worker->>Database: Update NodeRun (SUCCESS/FAILED)
Note over Backend,Frontend: SSE pushes update → node turns green/red
end
Worker->>Database: Update Run → COMPLETED
Note over Backend,Frontend: SSE pushes final update → stream closes
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | React 18, Vite, TailwindCSS v4, XYFlow (React Flow), TanStack Query | Interactive workflow canvas & real-time dashboard |
| Backend | FastAPI, SQLAlchemy (async), Alembic, Pydantic | REST API, SSE streaming, database ORM & migrations |
| Worker | Python asyncio, aio-pika | Background task processor with pluggable node handlers |
| Message Broker | RabbitMQ | Decoupled async task dispatch between API & worker |
| Database | SQLite (aiosqlite) | Lightweight persistent storage for workflows, runs & node execution data |
| Infrastructure | Docker Compose | Single-command orchestration of all 5 services |
- Drag-and-drop node canvas powered by XYFlow
- Add nodes via mid-edge "+" buttons or from a searchable catalog drawer
- Double-click any node to configure credentials and settings
- Auto-connection logic with bezier curve edges
- Parallel branching support via node handles
- Server-Sent Events (SSE) stream live execution data to the browser
- Nodes change color based on status:
- ⚪ Gray → Queued
- 🔵 Blue (pulsing) → Running
- 🟢 Green → Success
- 🔴 Red → Failed
- Edges turn green when connecting two successfully executed nodes
- Click any node to inspect its logs, input config, output data, and errors
- Component registry pattern for easy extension
- Built-in handlers: Manual Trigger, Logger, Browser, Gmail (IMAP)
- Each handler receives
(input_data, config)and returns output stored in the database
- Docker and Docker Compose
# Clone the repo
git clone https://github.com/aps08/mini-n8n.git
cd mini-n8n
# Start all services
docker compose up --build| Service | URL |
|---|---|
| 🖥 Frontend (Workflow UI) | http://localhost |
| ⚡ Backend (API) | http://localhost:8000/docs |
| 📨 RabbitMQ (Management) | http://localhost:15672 (guest/guest) |
| 💾 SQLite Viewer | http://localhost:8080 |
mini-n8n/
├── frontend/ # React + Vite application
│ └── src/
│ ├── components/ # Reusable UI components
│ │ ├── WorkflowNode.jsx # Custom ReactFlow node with status colors
│ │ ├── AddNodeEdge.jsx # Interactive edge with add/delete
│ │ ├── CatalogDrawer.jsx # Searchable node catalog sidebar
│ │ └── ConfigModal.jsx # Credential & settings editor
│ ├── hooks/ # Custom React hooks
│ │ ├── useWorkflow.js # Workflow CRUD + SSE real-time hook
│ │ └── useCatalog.js # Node catalog fetcher
│ └── pages/ # Route pages
│ ├── WorkflowDetail.jsx # Visual workflow builder canvas
│ ├── RunDetail.jsx # Real-time execution dashboard
│ └── Runs.jsx # Execution history list
├── backend/ # FastAPI application
│ └── app/
│ ├── api/ # API routes & dependency injection
│ │ ├── endpoints.py # REST + SSE endpoints
│ │ └── deps.py # FastAPI dependency providers
│ ├── model/ # SQLAlchemy ORM models
│ │ ├── workflow.py # Workflow, Node, Edge models
│ │ ├── run.py # Run, NodeRun models
│ │ └── catalog.py # Node catalog model
│ ├── repository/ # Database access layer
│ ├── schema/ # Pydantic request/response schemas
│ ├── services/ # Business logic layer
│ └── config/ # Database & app settings
├── worker/ # Background task processor
│ ├── main.py # RabbitMQ consumer entry point
│ ├── executor.py # Sequential node execution engine
│ ├── components/ # Pluggable node handlers
│ │ ├── base.py # BaseComponent abstract class
│ │ └── registry.py # Handler registry & implementations
│ ├── models/ # Worker-side ORM models
│ └── repository/ # Worker-side database access
├── rabbitmq/ # RabbitMQ Docker config
├── docker-compose.yml # Multi-service orchestration
└── README.md
Users create workflows on the visual canvas by selecting nodes from the catalog. Each node represents an automation step (e.g., "Manual Trigger", "Get Gmail Messages"). Nodes are connected via edges to define the execution order.
Double-clicking a node opens a configuration modal with two tabs:
- Credentials — Authentication details (email, API keys, passwords)
- Settings — Operational parameters (folder, max results, filters)
Clicking "Execute" triggers the following pipeline:
- The Backend creates a
Runrecord (status:PENDING) and publishes therun_idto RabbitMQ - The Frontend immediately navigates to the Run Detail page and opens an SSE connection
- The Worker picks up the task, updates the run to
RUNNING, and begins sequential node execution - For each node, the worker creates a
NodeRunrecord, executes the registered handler, and updates the record with output/errors/logs
The SSE endpoint polls the database every second, computes a state hash, and streams updates only when something changes. The frontend reacts instantly — coloring nodes, animating edges, and populating the inspector panel.
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
If you liked something about this repository, do give it a 🌟. It will motivate me come up with more such project. You can reach out to me on my social media given below.
If you liked this project, consider giving it a ⭐!