Skip to content

An Open Source alternative to n8n and gumloop designed for developers to integrate into their existing infrastructure.

License

Notifications You must be signed in to change notification settings

anonrose/loopty

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Loopty

High-scale, multi-tenant, embeddable workflow automation platform.

Loopty provides a visual DAG builder, secure node execution, and iframe-based embedding for integrating workflow automation into your SaaS product - similar to how Looker embeds dashboards.

🎵 The "Loop De Loop" Song - "You gotta do the loop de loop and pull, and your workflows are looking cool!"

CI License: MIT TypeScript Node.js

Features

  • Visual Workflow Builder - n8n-style drag-and-drop DAG editor with React Flow
  • 45+ Built-in Nodes - HTTP, code, AI, data transformation, CRM, communication channels, and more
  • Customer Communication - Multi-channel messaging (SMS, WhatsApp, Email, Push, Voice, In-App)
  • CRM Integrations - Native Salesforce, HubSpot, Pipedrive connectors
  • Advanced Orchestration - Branching (IF/Switch), loops, merging, A/B testing, rate limiting
  • Secure Execution - Sandboxed JS via isolated-vm, Docker containers for heavy workloads
  • Multi-Tenant - Organization isolation, RBAC, encrypted credential vault
  • Customer Management - Contacts, segments, event tracking, and analytics
  • Developer Studio - Full-featured dashboard for managing workflows and executions
  • Embeddable via Iframe - Signed embed URLs with white-label theming (like Looker)
  • Real-Time Monitoring - Live execution logs via WebSocket
  • Production Ready - PostgreSQL persistence, rate limiting, observability hooks

Studio Dashboard

The Studio provides a developer-friendly interface for building and managing workflows:

  • Workflow Editor - Visual canvas with node palette, drag-and-drop, and connection handles
  • Node Configuration - Dynamic settings forms with documentation for each node type
  • Execution History - View past runs with status, duration, and detailed logs
  • Credential Management - Securely store API keys and secrets for use in workflows
  • Real-time Updates - Live execution status and log streaming

Access Studio at /studio when running the API server.

Quick Start

Prerequisites

  • Node.js 20+
  • pnpm 9+
  • Docker and Docker Compose
  • PostgreSQL 15+ (or use Docker)
  • Redis 7+ (or use Docker)

Local Development

# Clone the repository
git clone https://github.com/anonrose/loopty.git
cd loopty

# Install dependencies
pnpm install

# Create environment file (see Configuration section for all variables)
cat > .env << 'EOF'
DATABASE_URL=postgres://loopty:loopty@localhost:5432/loopty
REDIS_URL=redis://localhost:6379
JWT_SECRET=dev-jwt-secret-change-in-production
EMBED_SECRET=dev-embed-secret-change-in-production
ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
PORT=4000
BASE_URL=http://localhost:4000
CORS_ORIGINS=*
NODE_ENV=development
EOF

# Start infrastructure (Postgres + Redis)
docker compose up -d postgres redis

# Run database migrations
pnpm db:migrate

# Seed development data
pnpm db:seed

# Seed development organization
psql $DATABASE_URL -c "INSERT INTO organizations (id, name, slug) VALUES ('00000000-0000-0000-0000-000000000001', 'Development Org', 'dev') ON CONFLICT DO NOTHING;"

# Build all packages
pnpm build

# Start development servers
pnpm dev

Access the applications:

Full Environment Reset

For a complete environment reset (useful when troubleshooting):

# Run the start-env script (cleans and rebuilds everything)
./start-env.sh

This script will:

  1. Stop and remove all Docker containers/volumes
  2. Prune Docker system
  3. Rebuild containers from scratch
  4. Run migrations and seed the database

Hot-Reload Development (Docker)

For development with hot reloading in Docker:

# Start all services with hot reload
docker compose -f docker-compose.dev.yml up

# Services will auto-restart when you edit source files

Docker (Self-Hosted)

# Build and start all services
docker compose up -d

# Check health
curl http://localhost:4000/health
# {"status":"ok","version":"0.1.0"}

# View logs
docker compose logs -f

Project Structure

loopty/
├── apps/
│   ├── api/              # HTTP API + WebSocket streaming + embed serving
│   ├── embed/            # Embeddable workflow editor (served via iframe)
│   ├── studio/           # Developer dashboard for workflow management
│   └── worker/           # BullMQ job processor + node execution
├── packages/
│   ├── db/               # Drizzle ORM schema + migrations
│   ├── engine/           # Workflow execution engine
│   ├── sdk/              # Iframe embed SDK (JS + React wrapper)
│   ├── shared/           # Zod schemas + node definitions
│   └── workflow-ui/      # React Flow canvas + n8n-style node components
├── docs/                 # Documentation
├── .github/              # CI/CD workflows + templates
├── docker-compose.yml    # Production deployment
└── docker-compose.dev.yml # Hot-reload development

API Endpoints

Workflows

Method Endpoint Description
GET /api/workflows List workflows
POST /api/workflows Create workflow
GET /api/workflows/:id Get workflow with versions
PATCH /api/workflows/:id Update workflow
DELETE /api/workflows/:id Delete workflow
POST /api/workflows/:id/versions Create new version
POST /api/workflows/:id/publish Publish a version

Executions

Method Endpoint Description
GET /api/executions List executions
GET /api/executions/:id Get execution details
POST /api/executions/workflows/:id/run Run a workflow
POST /api/executions/:id/resume Resume paused execution
POST /api/executions/:id/cancel Cancel execution
POST /api/executions/approve/:token Approve via token

Health

Method Endpoint Description
GET /health Basic health check
GET /health/db Database connectivity
GET /health/redis Redis connectivity

Nodes

Method Endpoint Description
GET /api/nodes/definitions Get all available node definitions with metadata

Credentials

Method Endpoint Description
GET /api/credentials List credentials (secrets never returned)
GET /api/credentials/:id Get credential metadata
POST /api/credentials Create credential (admin/owner only)
PATCH /api/credentials/:id Update credential (admin/owner only)
DELETE /api/credentials/:id Delete credential (admin/owner only)

Embed

Method Endpoint Description
POST /api/embed/url Generate signed embed URL for workflow
POST /api/embed/execution-url Generate signed URL for execution viewer
GET /api/embed/verify?token=... Verify embed token validity
GET /embed/workflow/:id Serve embedded workflow editor
GET /embed/execution/:id Serve embedded execution viewer

Configuration

Environment variables are automatically loaded from .env in the project root.

Required Variables

# Database (PostgreSQL connection string)
DATABASE_URL=postgres://loopty:loopty@localhost:5432/loopty

# Redis (for job queue)
REDIS_URL=redis://localhost:6379

# Authentication secrets (use strong random values in production!)
JWT_SECRET=your-secret-key-change-in-production          # 32+ characters
EMBED_SECRET=your-embed-secret-change-in-production      # 32+ characters
ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000  # 64 hex chars (32 bytes)

Server Configuration

# Server
PORT=4000                           # API server port
BASE_URL=http://localhost:4000      # Public base URL for embed URLs
CORS_ORIGINS=*                      # Comma-separated allowed origins (or * for all)
NODE_ENV=development                # development | production

Static Asset Paths (Production)

# Paths to built static assets (used in Docker/production)
EMBED_DIST_PATH=/app/apps/embed/dist
STUDIO_DIST_PATH=/app/apps/studio/dist
SDK_DIST_PATH=/app/packages/sdk/dist/index.umd.js

Worker Configuration

# Worker settings
WORKER_CONCURRENCY=10               # Number of concurrent jobs per worker
JOB_TIMEOUT_MS=300000               # Job timeout (5 minutes default)

Sandbox Configuration

# JavaScript sandbox limits (isolated-vm)
SANDBOX_TIMEOUT_MS=30000            # Execution timeout (30 seconds)
SANDBOX_MEMORY_MB=128               # Memory limit per execution

Optional Integrations

# AI nodes (OpenAI)
OPENAI_API_KEY=sk-...               # Required for AI chat, sentiment, classification nodes

# Monitoring (OpenTelemetry)
OTEL_ENABLED=true
OTEL_SERVICE_NAME=loopty
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318

# Logging
LOG_LEVEL=info                      # debug | info | warn | error
LOG_FORMAT=json                     # json | pretty

Generating Secrets

# Generate JWT/embed secret
openssl rand -base64 32

# Generate encryption key (32 bytes = 64 hex characters)
openssl rand -hex 32

Node Types

Loopty includes 45+ built-in nodes organized by category. Each node has comprehensive documentation accessible via the "Docs" tab in the Studio.

Triggers

Node Description
loopty.trigger.manual Start workflow manually or via API
loopty.trigger.schedule Cron-based scheduled execution
loopty.trigger.webhook HTTP webhook trigger with signature verification
loopty.trigger.event Event-driven trigger from external systems
loopty.trigger.form Form submission trigger

Logic & Flow Control

Node Description
loopty.logic.if Conditional branching (expression, compare, empty, regex)
loopty.logic.switch Multi-way routing with rules or value matching
loopty.logic.forEach Iterate over arrays with batch processing
loopty.logic.splitBatches Split arrays into configurable chunk sizes
loopty.logic.merge Combine multiple branches into one

Data Transformation

Node Description
loopty.data.filter Filter arrays with expression or conditions
loopty.data.sort Sort arrays by field (asc/desc)
loopty.data.limit Take first/last N items from array
loopty.data.aggregate Count, sum, average, min, max, group operations
loopty.data.splitOut Extract single field from array items

Core Nodes

Node Description
loopty.core.http Full HTTP client (all methods, auth, headers)
loopty.core.code Execute JavaScript in isolated sandbox

AI Nodes

Node Description
loopty.ai.chat OpenAI chat completions with function calling
loopty.ai.sentiment Analyze sentiment of text (positive/negative/neutral)
loopty.ai.classify Classify text into custom categories
loopty.ai.translate Translate text between languages
loopty.ai.summarize Summarize long text content
loopty.ai.extractor AI-powered web scraping with Playwright

Communication Nodes

Node Description
loopty.communication.sms Send SMS messages via provider
loopty.communication.whatsapp Send WhatsApp messages
loopty.communication.voice Initiate voice calls with TTS
loopty.communication.push Send push notifications
loopty.communication.inApp Send in-app notifications

CRM Integrations

Node Description
loopty.crm.salesforce Salesforce CRM operations (CRUD, queries)
loopty.crm.hubspot HubSpot CRM operations
loopty.crm.pipedrive Pipedrive CRM operations
loopty.crm.generic Generic CRM adapter for custom integrations

Customer Management

Node Description
loopty.customer.contact Create, update, lookup customer contacts
loopty.customer.segment Evaluate and manage customer segments

Scheduling & Flow

Node Description
loopty.scheduling.delay Delay execution for a duration or until timestamp
loopty.scheduling.scheduleSend Schedule message delivery for optimal times
loopty.scheduling.rateLimiter Rate limit workflow throughput
loopty.scheduling.abTest A/B test branching with traffic splits

Analytics

Node Description
loopty.analytics.track Track events and properties for analytics

Template & Validation

Node Description
loopty.template.render Render message templates with variables
loopty.forms.validate Validate data against schemas

Approval & Human-in-the-Loop

Node Description
loopty.approval.wait Pause workflow and wait for human approval

Utility Nodes

Node Description
loopty.utility.datetime Parse, format, add to dates
loopty.utility.crypto Hash, encrypt, encode, generate UUIDs
loopty.utility.htmlExtract Extract data from HTML with CSS selectors
loopty.utility.noop Pass-through node for debugging

Error Handling

Node Description
loopty.flow.stopError Stop workflow with error message
loopty.flow.tryCatch Wrap execution with error handling
loopty.flow.throw Conditionally throw errors
loopty.trigger.error Catch and handle workflow errors

Legacy Integrations

Node Description
loopty.integration.slack Send Slack messages via webhook
loopty.integration.email Send emails via SMTP
loopty.integration.database Query PostgreSQL/MySQL databases

Creating Custom Nodes

Custom nodes can be added by implementing the INodeDefinition interface:

import { defineNode } from "@loopty/shared";

export const myNode = defineNode({
  name: "mycompany.custom.node",
  displayName: "My Custom Node",
  category: "custom",
  params: [
    { name: "input", type: "string", required: true }
  ],
  async execute(input, context) {
    return { status: "success", output: { result: input } };
  }
});

Database Schema

Loopty uses PostgreSQL with Drizzle ORM. Key tables include:

Core Tables

Table Description
organizations Multi-tenant organization accounts
users User accounts with email/password auth
org_members Organization membership with roles (owner/admin/developer/viewer)
api_keys API keys for programmatic access
workflows Workflow definitions
workflow_versions Versioned workflow snapshots (nodes + edges)
executions Workflow execution records
execution_logs Detailed execution logs per node
credentials Encrypted credential storage
approvals Human approval requests

Customer Communication Tables

Table Description
contacts Customer contact records (email, phone, attributes)
templates Multi-channel message templates
segments Dynamic customer segments with rules
contact_events Customer event tracking
scheduled_jobs Scheduled/delayed job queue

Embedding Loopty

Loopty uses iframe-based embedding with signed URLs - similar to Looker. This approach provides:

  • Security - Signed tokens with expiration and permission scoping
  • Isolation - Complete CSS/JS isolation from your app
  • Simplicity - Works with any frontend framework (or none)

Quick Example

<!-- Option 1: Direct iframe -->
<iframe
  src="https://api.loopty.dev/embed/workflow/abc123?token=eyJhbGciOi..."
  width="100%"
  height="600"
></iframe>
// Option 2: JavaScript SDK
const embed = new LooptyEmbed({
  apiUrl: "https://api.loopty.dev",
  token: embedToken,
  container: "#workflow-editor"
});

embed.on("save", ({ workflow }) => console.log("Saved:", workflow));
embed.on("runStarted", ({ executionId }) => console.log("Run:", executionId));
// Option 3: React component
<LooptyIframe
  apiUrl="https://api.loopty.dev"
  token={embedToken}
  onSave={({ workflow }) => console.log("Saved:", workflow)}
  style={{ height: 600 }}
/>

Generating Embed URLs

Generate signed embed URLs from your backend:

curl -X POST https://api.loopty.dev/api/embed/url \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "workflowId": "abc123-def456",
    "permissions": ["view", "edit", "run"],
    "expiresIn": "1h"
  }'

See SDK Documentation for full API reference.

Development

Running Tests

# Run all tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Run with coverage
pnpm test:coverage

Code Quality

# Type checking
pnpm typecheck

# Linting
pnpm lint

# Build all packages
pnpm build

Database Migrations

# Generate migration from schema changes
pnpm db:generate

# Apply migrations
pnpm db:migrate

# Push schema directly (development only)
pnpm db:push

# Open Drizzle Studio (database GUI)
pnpm db:studio

# Seed development data
pnpm db:seed

Deployment

See Deployment Guide for detailed instructions on:

  • Docker Compose (production)
  • Kubernetes with Helm
  • Environment configuration
  • Security checklist

Architecture

┌────────────────────────────────────────────────────────────────────┐
│                        Host Application                             │
│                                                                    │
│   ┌────────────────────────────────────────────────────────────┐   │
│   │                        <iframe>                            │   │
│   │   ┌────────────────────────────────────────────────────┐   │   │
│   │   │                 Loopty Embed                       │   │   │
│   │   │             (Workflow Editor UI)                   │   │   │
│   │   └────────────────────────────────────────────────────┘   │   │
│   └────────────────────────────────────────────────────────────┘   │
│                        ▲ postMessage ▼                             │
│   ┌────────────────────────────────────────────────────────────┐   │
│   │                 Loopty SDK (Optional)                      │   │
│   └────────────────────────────────────────────────────────────┘   │
└────────────────────────────────────────────────────────────────────┘
                               │
                         ┌─────▼─────┐
                         │    API    │───────▶ ┌─────────────┐
                         │ (Express) │         │  PostgreSQL │
                         └─────┬─────┘         │  ─────────  │
                               │               │  • Workflows│
                               │               │  • Contacts │
                               │               │  • Segments │
                               │               │  • Events   │
                               │               └─────────────┘
                         ┌─────▼─────┐
                         │   Redis   │
                         │  (Queue)  │
                         └─────┬─────┘
                               │
                         ┌─────▼─────┐
                         │  Worker   │
                         │ (BullMQ)  │
                         └─────┬─────┘
                               │
         ┌─────────────────────┼─────────────────────┐
         │                     │                     │
   ┌─────▼─────┐         ┌─────▼─────┐         ┌─────▼─────┐
   │isolated-vm│         │    AI     │         │  Comms    │
   │   (JS)    │         │  (OpenAI) │         │ Channels  │
   └───────────┘         └───────────┘         └─────┬─────┘
                                                     │
                               ┌─────────────────────┼─────────────────────┐
                               │                     │                     │
                         ┌─────▼─────┐         ┌─────▼─────┐         ┌─────▼─────┐
                         │   SMS/    │         │   CRM     │         │   Push/   │
                         │ WhatsApp  │         │Integration│         │  In-App   │
                         └───────────┘         └───────────┘         └───────────┘

Security

  • All secrets encrypted at rest (AES-256-GCM)
  • JWT + API key authentication
  • Role-based access control (RBAC): Owner, Admin, Developer, Viewer
  • Sandboxed code execution (isolated-vm with memory/time limits)
  • HTTP egress allowlist
  • See SECURITY.md for vulnerability reporting

Contributing

We welcome contributions! Please read our Contributing Guide and Code of Conduct.

Documentation

License

MIT - see LICENSE.


Built with ❤️ by the Loopty team.

About

An Open Source alternative to n8n and gumloop designed for developers to integrate into their existing infrastructure.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages