DEV Community

Pool Camacho
Pool Camacho

Posted on • Originally published at z8run.org

I Built a Visual Flow Engine in Rust to Replace Node-RED and n8n

z8run visual flow editor demo

Why I started this project

I've spent years using Node-RED and n8n for workflow automation. They work well for small setups, but once you push them with hundreds of nodes and real-time data, things start to fall apart. Memory usage goes through the roof, a bad plugin can take down the whole process, and the JSON-over-WebSocket approach gets sluggish with large flows.

I wanted something faster. Something I could deploy as a single binary without dragging along node_modules. So I started building z8run, a visual flow engine written in Rust.

What does z8run do?

It's a self-hosted workflow automation tool with a drag-and-drop editor. Think Node-RED or n8n, but the backend is compiled Rust running on Tokio.

You design flows visually in the browser, connect nodes together, and deploy. The engine executes them as DAGs (directed acyclic graphs) with automatic parallelization.

What makes it different

  • Single binary deploy. No runtime, no dependencies. Just download and run.
  • WASM plugin sandbox. Plugins run inside wasmtime with explicit capability grants. You control what each plugin can access: network, filesystem, memory. A misbehaving plugin can't crash your server.
  • Binary WebSocket protocol. 11-byte header instead of full JSON payloads. The editor stays responsive even with complex flows.
  • Built-in credential vault. API keys and secrets are encrypted with AES-256-GCM at rest. No more plaintext credentials in config files.
  • 23 built-in nodes including 10 AI nodes (LLM, embeddings, vector store, classifier, etc.)

Architecture

The project is organized as a Rust workspace:

z8run/
├── z8run-core       # Flow engine, DAG validation, scheduler
├── z8run-protocol   # Binary WebSocket protocol
├── z8run-storage    # SQLite / PostgreSQL persistence
├── z8run-runtime    # WASM plugin sandbox (wasmtime)
└── z8run-api        # REST + WebSocket server (Axum)
Enter fullscreen mode Exit fullscreen mode

The scheduler compiles flows into parallel execution plans using topological ordering. Nodes that don't depend on each other run concurrently, which makes a big difference in flows with lots of branching.

Quick comparison

Feature z8run Node-RED n8n
Language Rust Node.js Node.js
WASM plugins Yes No No
AI nodes built-in 10 Community Limited
Binary protocol Yes JSON JSON
Credential vault AES-256-GCM Separate Built-in
Single binary Yes No No
License Apache-2.0 / MIT Apache-2.0 Sustainable Use

Built-in nodes

z8run ships with 23 nodes across 6 categories:

  • Input: HTTP In, Timer, Webhook (HMAC-SHA256 validation)
  • Process: Function, JSON Transform, HTTP Request, Filter
  • Output: Debug, HTTP Response
  • Logic: Switch (multi-rule routing), Delay
  • Data: Database (PostgreSQL, MySQL, SQLite), MQTT
  • AI: LLM, Embeddings, Classifier, Prompt Template, Text Splitter, Vector Store, Structured Output, Summarizer, AI Agent, Image Gen

The AI nodes are probably the feature I'm most proud of. You can chain a prompt template into an LLM call, pipe the result through a classifier, and store embeddings in a vector store. All visual, no code required.

Getting started

From source:

git clone https://github.com/z8run/z8run.git
cd z8run
cp .env.example .env
cargo build --release
cargo run --bin z8run -- serve
Enter fullscreen mode Exit fullscreen mode

Or with Docker:

docker pull ghcr.io/z8run/z8run-api:latest
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Server starts on http://localhost:7700.

# Health check
curl http://localhost:7700/api/v1/health

# Create a flow
curl -X POST http://localhost:7700/api/v1/flows \
  -H "Content-Type: application/json" \
  -d '{ "name": "My First Flow" }'
Enter fullscreen mode Exit fullscreen mode

Why Rust for this?

Flow engines are long-running processes. You need predictable memory usage, no GC pauses, and consistent latency when processing thousands of messages per second through a DAG.

Rust also has first-class WASM support through wasmtime, which gave me a production-grade sandbox for plugins without having to build one from scratch.

The tradeoff is obvious: Rust is slower to write than TypeScript. But for infrastructure that runs 24/7, I'll take that tradeoff every time.

What's next

z8run is at v0.2.0. Coming up:

  • Plugin marketplace
  • Helm chart for Kubernetes
  • Undo/redo and flow duplication in the editor
  • Rate limiting on the API

The project is open source and I'd love feedback:

If you've been looking for a faster alternative to Node-RED or n8n, give it a shot and let me know what you think.

Top comments (0)