Vyuh Node Flow

Vyuh Node Flow Banner

A flexible, high-performance node-based flow editor for Flutter applications. Build visual programming interfaces, workflow editors, interactive diagrams, and data pipelines with ease.

Pub Version Documentation License

Try the Live Demo · Get Started


Vyuh Node Flow in Action


Features

  • High Performance — Optimized rendering for smooth 60fps interactions
  • Viewport Controls — Pan, zoom, fit-to-view with animated transitions
  • Smart Connections — Bezier, smoothstep, step paths with validation rules
  • Connection Effects — Particles, flowing dashes, gradients, pulse & rainbow
  • Comprehensive Theming — Nodes, ports, connections, grid backgrounds & more
  • Keyboard Shortcuts — 20+ built-in actions, fully customizable
  • Multi-Select — Marquee selection, copy/paste, and bulk operations
  • Minimap & LOD — Bird's-eye navigation and zoom-based detail levels
  • Special Nodes — Groups for organization, comments for annotations
  • Serialization — Save and load flows from JSON with type-safe generics

Showcase

Demo Application
Demo Application
Full-featured demo with 20+ examples
Connection Effects
Connection Effects
Particles, gradients, flowing dashes & more
Minimap Navigation
Minimap Navigation
Bird's-eye view for large graphs
Level of Detail
Level of Detail
Auto-hide details when zoomed out
Viewport Animations
Viewport Animations
Smooth pan, zoom & fit-to-view
Theming System
Theming System
Light, dark & custom themes

Installation

dependencies:
  vyuh_node_flow: ^0.20.0

Quick Start

import 'package:flutter/material.dart';
import 'package:vyuh_node_flow/vyuh_node_flow.dart';

class FlowEditor extends StatefulWidget {
  @override
  State<FlowEditor> createState() => _FlowEditorState();
}

class _FlowEditorState extends State<FlowEditor> {
  late final controller = NodeFlowController<String, dynamic>(
    nodes: [
      Node<String>(
        id: 'node-1',
        type: 'input',
        position: const Offset(100, 100),
        data: 'Start',
        outputPorts: const [
          Port(id: 'out', name: 'Output', offset: Offset(2, 40)),
        ],
      ),
      Node<String>(
        id: 'node-2',
        type: 'output',
        position: const Offset(400, 100),
        data: 'End',
        inputPorts: const [
          Port(id: 'in', name: 'Input', offset: Offset(-2, 40)),
        ],
      ),
    ],
    connections: [
      Connection(
        id: 'conn-1',
        sourceNodeId: 'node-1',
        sourcePortId: 'out',
        targetNodeId: 'node-2',
        targetPortId: 'in',
      ),
    ],
  );

  @override
  Widget build(BuildContext context) {
    return NodeFlowEditor<String, dynamic>(
      controller: controller,
      theme: NodeFlowTheme.light,
      nodeBuilder: (context, node) => Padding(
        padding: const EdgeInsets.all(16),
        child: Text(node.data, style: const TextStyle(fontWeight: FontWeight.bold)),
      ),
    );
  }
}

Tip

Use a sealed class hierarchy for node data to get full type safety and pattern matching in your node builder.


Theming

Customize every visual aspect with the comprehensive theming system:

final customTheme = NodeFlowTheme.dark.copyWith(
  // Connection appearance
  connectionTheme: ConnectionTheme.dark.copyWith(
    style: ConnectionStyles.bezier,
    color: Colors.purple.shade300,
    animationEffect: ConnectionEffects.particles,
  ),

  // Grid background
  gridTheme: GridTheme.dark.copyWith(
    style: GridStyles.dots,
    color: Colors.white24,
  ),

  // Node styling
  nodeTheme: NodeTheme.dark.copyWith(
    borderRadius: BorderRadius.circular(12),
    selectedBorderColor: Colors.purple,
  ),
);

Note

See the Theming Guide for all available theme options including port shapes, connection effects, and custom builders.


Events

React to user interactions with the event system:

NodeFlowEditor<MyData, dynamic>(
  controller: controller,
  theme: theme,
  nodeBuilder: _buildNode,
  events: NodeFlowEvents<MyData, dynamic>(
    // Node events
    node: NodeEvents<MyData, dynamic>(
      onTap: (node) => print('Tapped: ${node.id}'),
      onMove: (node, delta) => print('Moving: ${node.id}'),
    ),

    // Connection validation
    connection: ConnectionEvents<MyData, dynamic>(
      onBeforeComplete: (context) {
        // Prevent self-connections
        if (context.sourceNode.id == context.targetNode.id) {
          return ConnectionValidationResult.invalid(
            reason: 'Cannot connect node to itself',
          );
        }
        return ConnectionValidationResult.valid();
      },
      onCreated: (connection) => print('Connected: ${connection.id}'),
    ),

    // Selection events
    selection: SelectionEvents<MyData, dynamic>(
      onChanged: (nodes) => print('Selected: ${nodes.length} nodes'),
    ),
  ),
);

Note

See the Events Guide for the complete event API including viewport, keyboard, and graph events.


Extensions

Add features through the modular extension system:

NodeFlowEditor<MyData, dynamic>(
  controller: controller,
  theme: theme,
  nodeBuilder: _buildNode,
  extensions: [
    // Navigation minimap
    MinimapExtension(visible: true),

    // Performance statistics overlay
    StatsExtension(),

    // Visual debugging overlays
    DebugExtension(mode: DebugMode.all),

    // Level of detail rendering
    LodExtension(enabled: true),
  ],
);

Documentation

For comprehensive guides and API reference, visit the documentation:

Topic Description
Installation Setup and requirements
Core Concepts Nodes, ports, connections, and controller
Theming Complete visual customization
Connection Effects Particles, flowing dashes, gradients & more
Events Interaction callbacks and validation
Serialization Save and load flows
Special Nodes Comments, groups, and annotations
API Complete API documentation
Examples Working code examples

Acknowledgments

Vyuh Node Flow is inspired by React Flow, the excellent node-based graph library for React.


License

MIT License - see LICENSE for details.


Made with ❤️ by the Vyuh team

Libraries

connections
Connection system - edges, endpoints, styling, and effects.
controller
NodeFlowController - the core state management for node graphs.
debug
Debug visualization layers and painters.
editor
Editor widgets - NodeFlowEditor, NodeFlowViewer, and configuration.
extensions
Extension system - events, extensions, and built-in extensions.
nodes
Node system - Node, GroupNode, CommentNode, and related classes.
ports
Port system - connection points on nodes.
spatial
Spatial indexing system for efficient hit testing and queries.
themes
Theming system - visual customization for all components.
utilities
Utility classes - helpers, shapes, and shared components.
viewport
Viewport system - pan, zoom, minimap, and graph data.
vyuh_node_flow
A flexible, high-performance node-based flow editor for Flutter.