Skip to content
frontend-architecture logo

ChainGraph Frontend Architecture

frontend-architecture

Frontend package architecture for ChainGraph visual flow editor. Use when working on apps/chaingraph-frontend, React components, Effector stores, XYFlow integration, UI components, providers, or hooks. Covers directory structure, domain organization, provider hierarchy, component patterns. Trigge...

SKILL.md

Full skill instructions

ChainGraph Frontend Architecture

This skill provides architectural guidance for the @badaitech/​chaingraph-frontend package - a React-based visual programming interface for designing computational graphs.

Package Overview

Location: apps/​chaingraph-frontend/ Purpose: Visual flow editor for ChainGraph using XYFlow Stack: React 19 + Vite + TypeScript + Effector + XYFlow + Tailwind + Radix UI

Directory Structure

apps/​chaingraph-frontend/​src/
├── main.tsx                 # Entry point, store initialization
├── App.tsx                  # Router setup
├── FlowLayout.tsx           # Layout: Sidebar + Flow
├── config.ts                # Environment configuration
│
├── components/
│   ├── flow/                # Main flow editor (see below)
│   ├── ui/                  # Radix UI components (31 files)
│   ├── sidebar/             # Navigation & flow list
│   ├── dnd/                 # Drag-and-drop (dnd-kit)
│   ├── debug/               # Debug tools
│   └── theme/               # Theme switching
│
├── store/                   # Effector state (15 domains)
│   ├── domains.ts           # Domain definitions
│   ├── initialization.ts    # App init orchestration
│   ├── nodes/               # Node CRUD, positions
│   ├── edges/               # Edge connections, anchors
│   ├── flow/                # Active flow, metadata
│   ├── ports-v2/            # Port values, configs, UI
│   ├── execution/           # Execution state
│   ├── trpc/                # tRPC clients (2 servers)
│   └── ...                  # 20+ more domains
│
├── hooks/                   # Global custom hooks
└── providers/               # Provider hierarchy

Flow Component Structure

components/​flow/
├── Flow.tsx                 # Main XYFlow container (13.6KB)
├── nodes/
│   ├── ChaingraphNode/      # Main node component (17 files)
│   │   ├── ChaingraphNodeOptimized.tsx  # Perf-optimized
│   │   └── ports/           # ArrayPort, ObjectPort
│   ├── AnchorNode/          # Edge anchor visualization
│   └── GroupNode/           # Group nodes
├── edges/
│   ├── components/          # Edge UI
│   └── utils/               # Edge calculations
└── hooks/                   # 18 flow-specific hooks
    ├── useNodeDragHandling.ts
    ├── useNodeSelection.ts
    ├── useFlowCopyPaste.ts
    ├── useKeyboardShortcuts.ts
    └── ...

Key Architectural Patterns

1. Two tRPC Clients

The app manages TWO separate WebSocket connections:

// Main Server (flows, nodes, edges)
$trpcClient → ws://localhost:3001

// Executor Server (execution events)
$trpcClientExecutor → ws://localhost:4021

2. Effector Domain-Based Stores

15 domains organized by feature:

DomainPurpose
nodesNode CRUD, positions, dimensions
edgesConnections, anchors, selection
flowActive flow, metadata
ports-v2Port values, configs, UI state
executionExecution state & events
trpctRPC client instances
xyflowXYFlow render optimization

3. Optimistic Updates + Debouncing

// Pattern: Local update → Debounce → Server sync
updateNodePositionLocal(event)  // Immediate UI update
// After NODE_POSITION_DEBOUNCE_MS (300ms)...
updateNodePositionFx(event)     // Send to server

4. Provider Hierarchy

ChainGraphProvider
  └─ RootProvider
      ├─ ThemeProvider
      ├─ ReactFlowProvider
      │   ├─ ZoomProvider
      │   ├─ DndContextProvider
      │   └─ MenuPositionProvider
      └─ [children]

Store Patterns

Creating a Store

import { nodesDomain } from '../​domains'

// Events (commands)
export const addNode = nodesDomain.createEvent<INode>()
export const removeNode = nodesDomain.createEvent<string>()

// Effects (async operations)
export const addNodeFx = nodesDomain.createEffect(async (params) => {
  const client = $trpcClient.getState()
  return client.flow.addNode.mutate(params)
})

// Stores
export const $nodes = nodesDomain.createStore<Record<string, INode>>({})
  .on(addNode, (nodes, node) => ({ ...nodes, [node.id]: node }))
  .on(removeNode, (nodes, id) => {
    const { [id]: _, ...rest } = nodes
    return rest
  })

// Derived stores
export const $selectedNodeIds = combine($nodes, (nodes) =>
  Object.keys(nodes).filter(id => nodes[id].isSelected)
)

Global Reset Pattern

All stores support global reset:

import { globalReset } from '../​global'

$myStore.reset(globalReset)

Component Patterns

Using Effector in Components

import { useUnit } from 'effector-react'
import { $nodes, addNode } from '@/​store/​nodes'

function MyComponent() {
  const [nodes, handleAddNode] = useUnit([$nodes, addNode])
  // ...
}

Lazy Loading

const LazyComponent = lazy(() => import('./​HeavyComponent'))

// In render
<Suspense fallback={<Loading />}>
  <LazyComponent />
</​Suspense>

Performance Considerations

  1. Node Position Interpolation - Smooth animations via position-interpolation-advanced.ts
  2. XYFlow Store - Combined render data per node to reduce re-renders
  3. Effector Sampling - Accumulate rapid updates, sample at intervals
  4. Debounce Constants:
    • NODE_POSITION_DEBOUNCE_MS = 300
    • NODE_DIMENSIONS_DEBOUNCE_MS = 500
    • NODE_UI_DEBOUNCE_MS = 1000

Key Files Reference

FilePurpose
src/​main.tsxApp bootstrap
src/​store/​initialization.tsInit orchestration
src/​store/​domains.ts13 Effector domains
src/​components/​flow/​Flow.tsxMain flow component
src/​providers/​ChainGraphProvider.tsxTop-level provider

Best Practices

  1. Use domain-based stores - Create stores within appropriate domains
  2. Optimistic updates first - Update local store immediately, sync to server with debounce
  3. Avoid direct tRPC calls in components - Use Effector effects
  4. Use useUnit - Not useStore or useEvent separately
  5. Reset on globalReset - All stores should support global reset
  6. Lazy load heavy components - Especially documentation/​tooltips
  7. Use ports-v2 - Legacy ports/ is being phased out

Related Skills

  • effector-patterns - Effector state management anti-patterns
  • xyflow-patterns - XYFlow integration patterns
  • subscription-sync - Real-time data synchronization
  • optimistic-updates - Optimistic UI patterns
  • chaingraph-concepts - Core domain concepts
  • trpc-patterns - tRPC framework patterns
  • trpc-flow-editing - Flow editing tRPC procedures

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View