DAG Visual Editor Design
Design modern, intuitive DAG and workflow visual editors. This skill captures best practices from industry leaders like n8n, ComfyUI, Retool Workflows, and React Flow — prioritizing clarity over complexity.
Philosophy: LEGO, Not LabView
Traditional node editors (LabView, Max/MSP, older VFX tools) suffer from:
-
Dense, cluttered interfaces
-
Overwhelming port/connection complexity
-
Steep learning curves
-
"Spaghetti" wire syndrome
Modern DAG editors take a different approach:
-
LEGO-like composability — snap blocks together
-
Progressive disclosure — show complexity only when needed
-
Clear data flow — left-to-right or top-to-bottom
-
Minimal chrome — the content IS the interface
Core Design Principles
- Nodes as First-Class Components
Nodes should feel like self-contained units, not wiring terminals.
┌─────────────────────────────┐ │ 🔄 Transform Data │ ← Clear title with icon ├─────────────────────────────┤ │ Input: users.json │ ← Inline config, not ports │ Output: filtered_users │ ├─────────────────────────────┤ │ ▶ Run │ ⚙ Config │ 📋 Docs │ ← Actions in footer └─────────────────────────────┘
Bad (LabView style):
●─┬─● ●─●
│ │
┌───┴───┐ ┌─┴─┐ │ Node │─│ N │ └───┬───┘ └─┬─┘ │ │ ●─┴─● ●─┴─●
Good (Modern style):
┌──────────┐ ┌──────────┐ │ Input │ ───▶ │ Process │ ───▶ [Output] └──────────┘ └──────────┘
- Connection Semantics
Pattern When to Use Visual
Implicit Sequential flows Vertical stack, no lines
Explicit minimal Branching logic Single clear edge
Bundled Multiple data channels Grouped/labeled edges
Animated Execution/data flow Particles along edges
Key insight from ComfyUI: Show data flowing through edges during execution. Users understand what's happening.
- Handle Design
Avoid: Multiple tiny ports crammed on node sides
Prefer:
-
Single input handle (top or left)
-
Single output handle (bottom or right)
-
Type indicators via color/shape only when needed
-
Handle reveals on hover for clean default state
- Layout Algorithms
Auto-layout is critical. Users shouldn't manually arrange nodes.
// Dagre layout (hierarchical, left-to-right) const layout = dagre.graphlib.Graph() .setGraph({ rankdir: 'LR', ranksep: 80, nodesep: 40 }) .setDefaultEdgeLabel(() => ({}));
// ELK (more sophisticated, handles complex graphs) const elk = new ELK(); await elk.layout(graph, { algorithm: 'layered', 'elk.direction': 'RIGHT', 'elk.layered.spacing.nodeNodeBetweenLayers': 100, });
- Minimap & Navigation
Essential for complex workflows:
-
Minimap in corner (toggleable)
-
Fit-to-view on double-click background
-
Breadcrumbs for nested/grouped nodes
-
Search to jump to nodes
Technology Stack
React Flow (Recommended)
import ReactFlow, { Background, Controls, MiniMap, useNodesState, useEdgesState, } from 'reactflow';
function WorkflowEditor() { const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
return ( <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} fitView > <Background variant="dots" gap={16} /> <MiniMap /> <Controls /> </ReactFlow> ); }
Custom Node Template
const SkillNode = ({ data, selected }) => ( <div className={cn( "rounded-lg border-2 bg-white shadow-md min-w-[200px]", selected ? "border-blue-500" : "border-gray-200" )}> {/* Header */} <div className="flex items-center gap-2 px-3 py-2 bg-gray-50 rounded-t-lg"> <span className="text-lg">{data.icon}</span> <span className="font-medium">{data.label}</span> </div>
{/* Body - preview of config */}
<div className="px-3 py-2 text-sm text-gray-600">
{data.preview}
</div>
{/* Handles */}
<Handle type="target" position={Position.Left} />
<Handle type="source" position={Position.Right} />
</div> );
Interaction Patterns
Edge Drawing
-
Click source handle → drag → release on target handle
-
Show valid drop targets while dragging
-
Snap to nearest compatible handle
-
Allow edge deletion via backspace or context menu
Node Creation
-
Context menu — Right-click on canvas
-
Quick add — Type / to search nodes (like Notion)
-
Drag from library — Sidebar with categorized nodes
-
Connection drop — Drop edge on empty space → node picker
Keyboard Shortcuts
Key Action
Delete / Backspace
Remove selected
Cmd/Ctrl + D
Duplicate
Cmd/Ctrl + G
Group selected
Cmd/Ctrl + Z
Undo
/
Quick node search
Space + Drag
Pan canvas
Scroll
Zoom
Visual Hierarchy
Node States
/* Default */ .node { border: 2px solid #e5e7eb; }
/* Selected */ .node.selected { border-color: #3b82f6; box-shadow: 0 0 0 2px rgba(59,130,246,0.3); }
/* Running */ .node.running { border-color: #f59e0b; animation: pulse 1s infinite; }
/* Completed */ .node.completed { border-color: #10b981; }
/* Error */ .node.error { border-color: #ef4444; background: #fef2f2; }
Edge Animation During Execution
.edge-animated path { stroke-dasharray: 5; animation: dash 0.5s linear infinite; }
@keyframes dash { to { stroke-dashoffset: -10; } }
Anti-Patterns to Avoid
-
Too many handle types — Color-code sparingly, not per data type
-
Wire spaghetti — Use auto-layout, not manual positioning
-
Hidden complexity — Don't collapse essential config into modals
-
No execution feedback — Show what's running and what's waiting
-
Monolithic nodes — Break complex operations into composable pieces
-
Ignoring touch — Support touch/pen for tablet users
Case Studies
n8n
-
Clean card-based nodes
-
Inline parameter editing
-
Execution visualization with timing
-
Excellent error highlighting
ComfyUI
-
Familiar to VFX/3D artists
-
Lazy evaluation (only runs changed nodes)
-
Shareable workflow JSON files
-
Preview widgets inside nodes
Retool Workflows
-
Conditional branching UI
-
Loop visualization
-
Strong typing with visual indicators
-
Enterprise-grade error handling
Implementation Checklist
-
React Flow or similar graph library
-
Auto-layout with Dagre/ELK
-
Custom node components with consistent design
-
Edge animation during execution
-
Minimap for navigation
-
Keyboard shortcuts
-
Undo/redo system
-
Node search/quick add
-
Save/load workflow state
-
Export to JSON/image
Resources
-
React Flow Documentation
-
xyflow/awesome-node-based-uis
-
n8n Node UI Design
-
ComfyUI Technical Deep Dive
-
ELK.js Layout Algorithms
-
Dagre Layout