Files
ComfyUI_frontend/docs/adr/0002-crdt-based-layout-system.md
Christian Byrne c773230b21 feat: Implement CRDT-based layout system for Vue nodes (#4959)
* feat: Implement CRDT-based layout system for Vue nodes

Major refactor to solve snap-back issues and create single source of truth for node positions:

- Add Yjs-based CRDT layout store for conflict-free position management
- Implement layout mutations service with clean API
- Create Vue composables for layout access and node dragging
- Add one-way sync from layout store to LiteGraph
- Disable LiteGraph dragging when Vue nodes mode is enabled
- Add z-index management with bring-to-front on node interaction
- Add comprehensive TypeScript types for layout system
- Include unit tests for layout store operations
- Update documentation to reflect CRDT architecture

This provides a solid foundation for both single-user performance and future real-time collaboration features.

Co-Authored-By: Claude <noreply@anthropic.com>

* style: Apply linter fixes to layout system

* fix: Remove unnecessary README files and revert services README

- Remove unnecessary types/README.md file
- Revert unrelated changes to services/README.md
- Keep only relevant documentation for the layout system implementation

These were issues identified during PR review that needed to be addressed.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: Clean up layout store and implement proper CRDT operations

- Created dedicated layoutOperations.ts with production-grade CRDT interfaces
- Integrated existing QuadTree spatial index instead of simple cache
- Split composables into separate files (useLayout, useNodeLayout, useLayoutSync)
- Cleaned up operation handlers using specific types instead of Extract
- Added proper operation interfaces with type guards and extensibility
- Updated all type references to use new operation structure

The layout store now properly uses the existing QuadTree infrastructure for
efficient spatial queries and follows CRDT best practices with well-defined
operation interfaces.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: Extract services and split composables for better organization

- Created SpatialIndexManager to handle QuadTree operations separately
- Added LayoutAdapter interface for CRDT abstraction (Yjs, mock implementations)
- Split GraphNodeManager into focused composables:
  - useNodeWidgets: Widget state and callback management
  - useNodeChangeDetection: RAF-based geometry change detection
  - useNodeState: Node visibility and reactive state management
- Extracted constants for magic numbers and configuration values
- Updated layout store to use SpatialIndexManager and constants

This improves code organization, testability, and makes it easier to swap
CRDT implementations or mock services for testing.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add node slots to layout tree

* Revert "Add node slots to layout tree"

This reverts commit 460493a620.

* Remove slots from layoutTypes

* Totally not scuffed renderer and adapter

* Revert "Totally not scuffed renderer and adapter"

This reverts commit 2b9d83efb8.

* Revert "Remove slots from layoutTypes"

This reverts commit 18f78ff786.

* Reapply "Add node slots to layout tree"

This reverts commit 236fecb549.

* Revert "Add node slots to layout tree"

This reverts commit 460493a620.

* docs: Replace architecture docs with comprehensive ADR

- Add ADR-0002 for CRDT-based layout system decision
- Follow established ADR template with persuasive reasoning
- Include performance benefits, collaboration readiness, and architectural advantages
- Update ADR index

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Benjamin Lu <benjaminlu1107@gmail.com>
2025-08-29 13:59:48 -04:00

4.7 KiB

2. CRDT-Based Layout System

Date: 2024-08-16

Status

Accepted

Context

ComfyUI's node graph editor faces fundamental architectural limitations that prevent us from achieving our product goals:

The Problem

In the current system, each node manages its own position directly within LiteGraph. This creates several critical issues:

  1. Performance Degradation: Every UI update requires traversing the entire graph to detect changes. With graphs containing 100+ nodes, this polling-based approach causes visible lag during interactions.

  2. Snap-Back Hell: Multiple systems (LiteGraph canvas, Vue widgets, drag handlers) fight over node positions. Users experience frustrating "snap-back" where nodes jump between positions during drag operations.

  3. No Collaboration Path: Direct mutation of node positions makes real-time collaboration impossible. There's no way to merge concurrent edits from multiple users without conflicts.

  4. Limited Renderer Options: Position data is tightly coupled to LiteGraph's canvas renderer, blocking us from implementing WebGL rendering for large graphs or accessibility-focused DOM rendering.

  5. Missing Features: Without a proper event system, we can't implement undo/redo, animation systems, or viewport culling efficiently.

Why Now?

  • User complaints about performance with large workflows are increasing
  • The AI art community expects real-time collaboration (see Figma, Miro)
  • Accessibility requirements demand alternative rendering modes
  • The technical debt is compounding with each new feature

Decision

We will implement a centralized layout tree using CRDT (Conflict-free Replicated Data Types) as the single source of truth for all spatial data.

Key Design Choices

  1. CRDT-Based Layout Tree: Use Yjs to maintain a centralized tree structure that owns all node positions, sizes, and spatial relationships.

  2. Command Pattern: Every position change is an explicit command/operation rather than direct mutation. This enables:

    • Precise operation history for undo/redo
    • Automatic conflict resolution for concurrent edits
    • Event stream for observers without polling
  3. Unidirectional Data Flow:

    User Input → Layout Commands → CRDT Tree → Renderers
    

    LiteGraph becomes a pure renderer that receives position updates, never mutates them.

  4. Spatial Indexing: The tree structure naturally supports a QuadTree spatial index for O(log n) viewport queries instead of O(n) full scans.

Why CRDT?

CRDTs solve our core problems elegantly:

  • Local-First: Works perfectly for single-user while being collaboration-ready
  • Automatic Conflict Resolution: No more snap-back from competing updates
  • Event-Driven: Changes propagate through observers, not polling
  • Memory Efficient: Only changed portions of the tree are updated

Implementation Approach

Phase 1: Build alongside existing system

  • Layout tree observes LiteGraph changes initially
  • Gradually migrate interactions to command pattern
  • Maintain full backwards compatibility

Phase 2: Invert control

  • Layout tree becomes source of truth
  • LiteGraph receives updates via one-way sync
  • Enable alternative renderers

Consequences

Positive

  • 10x Performance: Viewport culling and spatial indexing eliminate full graph traversals
  • Multiplayer Ready: CRDT foundation enables real-time collaboration without architecture changes
  • Undo/Redo: Command pattern makes history trivial to implement
  • Renderer Flexibility: Clean separation allows WebGL, DOM, or hybrid rendering
  • Developer Experience: Clear data flow and event system simplify debugging

Negative

  • Learning Curve: Team needs to understand CRDT concepts and command pattern
  • Migration Complexity: Existing code must be carefully migrated to new system
  • Initial Memory Overhead: ~30KB for Yjs library + operation history storage

Mitigations

  • Provide clear migration guides and examples
  • Build compatibility layer for gradual migration
  • Implement operation history pruning for long-running sessions

Notes

This architecture aligns with modern state management patterns seen in Figma, Linear, and other collaborative tools. The investment in CRDT infrastructure pays dividends across multiple feature areas and positions ComfyUI as a modern, collaborative AI workflow tool.

The command pattern also opens doors for:

  • Macro recording and playback
  • Automated testing of UI interactions
  • Remote control via API
  • AI-assisted layout optimization

References