Skip to content

aarynverma/react-flow-builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flow Builder

A visual flow builder for constructing conditional node graphs and exporting them as JSON. Built with React 18 + TypeScript + React Flow v12 + Zustand.


Quick Start

npm install
npm run dev

Open http://localhost:5173 (or whichever port Vite assigns — check your terminal).


Available Scripts

Command Description
npm run dev Start the development server
npm run build Type-check and build for production
npm run preview Preview the production build locally
npm run test Run unit tests (Vitest)

How to Use

Action How
Add a node Click + Add Node in the toolbar or the canvas button
Connect nodes Drag from a node's bottom handle to another's top handle
Edit a node Click any node — the sidebar opens
Set start node Click ⚑ on the node card, or use Set as Start in the sidebar
Delete a node Click ✕ on the node card, or use Delete Node in the sidebar (both prompt inline confirmation)
Delete a node (keyboard) Click a node to select it, then press Delete
Delete an edge Select the edge on the canvas and press Delete, or remove it via the sidebar edge card
Clear everything Clear All in the toolbar → confirm
Import JSON JSON Preview panel → ↑ Import → paste → Import & Reconstruct
Copy JSON JSON Preview panel → ⎘ Copy
Download JSON JSON Preview panel → ↓ Download

Responsive Layout

Screen size Layout
Desktop ≥ 1024px Full 3-panel layout: Sidebar · Canvas · JSON Preview
Tablet 640–1023px Sidebar + Canvas; toggle JSON panel via the {} JSON button in the toolbar
Mobile < 640px Single panel at a time; switch between Canvas / Edit / JSON using the bottom tab bar

Schema Format

{
  "start_node_id": "greeting",
  "nodes": [
    {
      "id": "greeting",
      "description": "Initial greeting step",
      "prompt": "Hello! How can I help you today?",
      "edges": [
        {
          "to_node_id": "collect_info",
          "condition": "user_responds",
          "parameters": { "timeout": "30s" }
        }
      ]
    },
    {
      "id": "collect_info",
      "description": "Collect user information",
      "prompt": "Could you please share your name and issue?",
      "edges": []
    }
  ]
}

Project Structure

src/
├── __tests__/
│   └── validation.test.ts    — Unit tests for validation logic (Vitest)
├── components/
│   ├── Canvas/
│   │   ├── FlowCanvas.tsx    — React Flow canvas wrapper + provider
│   │   ├── CustomNode.tsx    — Draggable node with start/error/selected states
│   │   └── CustomEdge.tsx    — Bezier edge with condition label + delete button
│   ├── Sidebar/
│   │   └── NodeSidebar.tsx   — Node editor panel (ID, description, prompt, edges)
│   ├── JsonPreview/
│   │   └── JsonPreview.tsx   — Live JSON output with import / copy / download
│   ├── Toolbar/
│   │   └── Toolbar.tsx       — Top bar with node count, validation status, responsive controls
│   └── ErrorBoundary.tsx     — React error boundary for graceful crash recovery
├── hooks/
│   └── useFlowStore.ts       — Zustand store with localStorage persistence
├── types/
│   └── flow.types.ts         — TypeScript interfaces for nodes, edges, schema
├── utils/
│   ├── validation.ts         — Live validation rules (uniqueness, required fields, connectivity)
│   └── schema.ts             — Schema builder utility
├── App.tsx                   — Layout + responsive breakpoint logic
├── main.tsx
└── index.css

Design Decisions

Area Choice Reason
Flow library @xyflow/react v12 Most mature React flow library — full TS support, custom nodes/edges, built-in drag & pan
State Zustand Single store keeps Canvas, Sidebar, and JSON Preview in sync without prop-drilling
Persistence Zustand persist middleware Flow state is automatically saved to localStorage and restored on page reload
Validation Live on every mutation Errors appear instantly in the sidebar (inline), on the node (red border), and in the JSON panel
Schema source of truth flowNodes[] array React Flow nodes/edges are derived visual state; the schema is always derived from flowNodes
Confirmations Inline UI Delete/Clear actions use in-component confirm steps instead of window.confirm (which is blocked by some browsers)
Responsive layout React breakpoint hook Panel visibility is controlled via useBreakpoint() + inline style={{ display }} rather than pure CSS, avoiding React Flow sizing conflicts
Edge labels EdgeLabelRenderer Enables interactive labels and a delete button directly on the edge
ID uniqueness Enforced on blur Prevents rename collisions without blocking typing mid-word; reverts to original on invalid blur
Import Full schema reconstruction Parses JSON and rebuilds both flowNodes and the visual RF nodes with an auto-layout grid
Error handling React Error Boundary Catches rendering errors gracefully and shows a recovery UI

Validations

Errors (block valid JSON badge):

  • Start node must be designated and must exist in the graph
  • Node IDs must be unique and non-empty
  • Description and prompt fields are required on every node
  • Edge target node must be selected and must exist in the graph
  • Edge condition text is required

Warnings:

  • Nodes with no incoming edges (other than the start node) are flagged as disconnected

Deployment

# Build
npm run build

# Vercel
npx vercel --prod

Releases

No releases published

Packages

 
 
 

Contributors