Skip to content
Back to skills

System Design Visualizer Tool

BSecurity

Transform static system design diagrams into interactive, explorable visualizations using AI-powered analysis and React Flow.

  • 6 stars
  • 0 votes
  • 0 copies
  • 9 views
  • Added September 8, 2026
developmentjavascriptgojavabashreactnodeawsgitapidatabase

Works with

  • cli
  • api

Security analysis

B89/100
  • highPerforms destructive filesystem operations
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 8, 2026

npx -y skills add Aradotso/design-skills --skill system-design-visualizer-tool --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of System Design Visualizer Tool?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for System Design Visualizer Tool
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/aradotso-system-design-visualizer-tool/badge)](https://www.skillsdirectory.com/skills/aradotso-system-design-visualizer-tool)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: system-design-visualizer-tool
description: Transform static system design diagrams into interactive, explorable visualizations using AI-powered analysis and React Flow.
triggers:
  - "convert my architecture diagram to interactive visualization"
  - "transform system design image into mermaid diagram"
  - "make my flowchart interactive with react flow"
  - "analyze this system design diagram with ai"
  - "create explorable visualization from architecture image"
  - "generate interactive graph from system design"
  - "turn static diagram into clickable components"
  - "visualize system architecture interactively"
---

# System Design Visualizer Tool

> Skill by [ara.so](https://ara.so) — Design Skills collection.

System Design Visualizer is an AI-powered tool that transforms static system design images (architecture diagrams, flowcharts, etc.) into interactive, explorable visualizations. It uses OpenAI's GPT-4o Vision to analyze uploaded images, generates Mermaid.js diagrams, and converts them into interactive React Flow graphs with detailed component information.

## Installation

```bash
git clone https://github.com/mallahyari/system-design-visualizer.git
cd system-design-visualizer
npm install
```

### Environment Configuration

Create a `.env` file in the root directory:

```env
VITE_OPENAI_API_KEY=your_openai_api_key_here
```

**Note**: If no API key is provided, the app runs in Mock Mode with sample data.

### Start Development Server

```bash
npm run dev
```

The app will be available at `http://localhost:5173`.

## Core Architecture

The project uses a React + Vite setup with three main visualization stages:

1. **Image Upload**: Accepts system design diagrams
2. **Mermaid Generation**: AI converts image to Mermaid.js code
3. **Interactive Graph**: Converts Mermaid to React Flow visualization

## Key Components

### Image Upload Component

```javascript
import { useState } from 'react';
import { Upload } from 'lucide-react';

function ImageUploader({ onImageUpload }) {
  const [isDragging, setIsDragging] = useState(false);

  const handleDrop = (e) => {
    e.preventDefault();
    setIsDragging(false);
    const file = e.dataTransfer.files[0];
    if (file && file.type.startsWith('image/')) {
      const reader = new FileReader();
      reader.onload = (e) => onImageUpload(e.target.result);
      reader.readAsDataURL(file);
    }
  };

  return (
    <div
      onDrop={handleDrop}
      onDragOver={(e) => { e.preventDefault(); setIsDragging(true); }}
      onDragLeave={() => setIsDragging(false)}
      className={`border-2 border-dashed rounded-lg p-12 text-center ${
        isDragging ? 'border-blue-500 bg-blue-50' : 'border-gray-300'
      }`}
    >
      <Upload className="mx-auto h-12 w-12 text-gray-400" />
      <p className="mt-4 text-sm text-gray-600">
        Drag and drop your system design image here
      </p>
    </div>
  );
}
```

### OpenAI Integration for Image Analysis

```javascript
import OpenAI from 'openai';

const openai = new OpenAI({
  apiKey: import.meta.env.VITE_OPENAI_API_KEY,
  dangerouslyAllowBrowser: true
});

async function analyzeSystemDesign(imageDataUrl) {
  const response = await openai.chat.completions.create({
    model: "gpt-4o",
    messages: [
      {
        role: "user",
        content: [
          {
            type: "text",
            text: "Analyze this system design diagram and generate a Mermaid.js diagram representing the architecture. Include all components, connections, and relationships."
          },
          {
            type: "image_url",
            image_url: { url: imageDataUrl }
          }
        ]
      }
    ],
    max_tokens: 2000
  });

  return response.choices[0].message.content;
}
```

### Mermaid to React Flow Conversion

```javascript
function parseMermaidToReactFlow(mermaidCode) {
  const nodes = [];
  const edges = [];
  
  // Parse mermaid syntax (simplified example)
  const lines = mermaidCode.split('\n');
  const nodeMap = new Map();
  let nodeId = 0;
  
  lines.forEach((line, index) => {
    // Match patterns like: A[Load Balancer] --> B[Web Server]
    const connectionMatch = line.match(/(\w+)\[(.*?)\]\s*-->\s*(\w+)\[(.*?)\]/);
    
    if (connectionMatch) {
      const [_, sourceId, sourceLabel, targetId, targetLabel] = connectionMatch;
      
      // Add source node if not exists
      if (!nodeMap.has(sourceId)) {
        nodes.push({
          id: sourceId,
          type: 'custom',
          position: { x: 100, y: nodeId * 100 },
          data: { label: sourceLabel }
        });
        nodeMap.set(sourceId, true);
        nodeId++;
      }
      
      // Add target node if not exists
      if (!nodeMap.has(targetId)) {
        nodes.push({
          id: targetId,
          type: 'custom',
          position: { x: 400, y: nodeId * 100 },
          data: { label: targetLabel }
        });
        nodeMap.set(targetId, true);
        nodeId++;
      }
      
      // Add edge
      edges.push({
        id: `${sourceId}-${targetId}`,
        source: sourceId,
        target: targetId,
        type: 'smoothstep'
      });
    }
  });
  
  return { nodes, edges };
}
```

### Interactive React Flow Graph

```javascript
import ReactFlow, { 
  MiniMap, 
  Controls, 
  Background,
  useNodesState,
  useEdgesState 
} from 'reactflow';
import 'reactflow/dist/style.css';

function InteractiveGraph({ mermaidCode }) {
  const { nodes: initialNodes, edges: initialEdges } = parseMermaidToReactFlow(mermaidCode);
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
  const [selectedNode, setSelectedNode] = useState(null);

  const onNodeClick = async (event, node) => {
    setSelectedNode(node);
    
    // Get detailed info about the component using AI
    const details = await getComponentDetails(node.data.label);
    setSelectedNode({ ...node, details });
  };

  return (
    <div className="h-screen">
      <ReactFlow
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        onNodeClick={onNodeClick}
        fitView
      >
        <Background />
        <Controls />
        <MiniMap />
      </ReactFlow>
      
      {selectedNode && (
        <ComponentDetailsPanel node={selectedNode} />
      )}
    </div>
  );
}
```

### Component Details Analysis

```javascript
async function getComponentDetails(componentName) {
  const response = await openai.chat.completions.create({
    model: "gpt-4o",
    messages: [
      {
        role: "user",
        content: `Given a system design component named "${componentName}", provide:
1. Likely technology stack
2. Primary role in the architecture
3. Common configuration considerations
4. Best practices

Format as JSON with keys: technologies, role, configuration, bestPractices`
      }
    ],
    max_tokens: 500
  });

  return JSON.parse(response.choices[0].message.content);
}
```

### Custom Node Component

```javascript
import { Handle, Position } from 'reactflow';

function CustomNode({ data, selected }) {
  return (
    <div className={`px-4 py-2 rounded-lg border-2 bg-white shadow-md ${
      selected ? 'border-blue-500' : 'border-gray-300'
    }`}>
      <Handle type="target" position={Position.Top} />
      <div className="font-semibold text-sm">{data.label}</div>
      {data.description && (
        <div className="text-xs text-gray-500 mt-1">{data.description}</div>
      )}
      <Handle type="source" position={Position.Bottom} />
    </div>
  );
}

const nodeTypes = {
  custom: CustomNode
};
```

## Mock Mode (No API Key)

When running without an OpenAI API key, use mock data:

```javascript
function getMockMermaidDiagram() {
  return `graph TB
    A[Load Balancer] --> B[Web Server 1]
    A --> C[Web Server 2]
    B --> D[Application Server]
    C --> D
    D --> E[Database Master]
    D --> F[Cache Layer]
    E --> G[Database Replica]`;
}

function getMockComponentDetails(componentName) {
  const mockDetails = {
    'Load Balancer': {
      technologies: ['NGINX', 'HAProxy', 'AWS ELB'],
      role: 'Distributes incoming traffic across multiple servers',
      configuration: 'Health checks, SSL termination, routing rules',
      bestPractices: 'Use multiple availability zones, enable auto-scaling'
    },
    // Add more mock data as needed
  };
  
  return mockDetails[componentName] || {
    technologies: ['Generic'],
    role: 'System component',
    configuration: 'Standard setup',
    bestPractices: 'Follow industry standards'
  };
}
```

## Full App Integration Example

```javascript
import { useState } from 'react';
import ReactFlow from 'reactflow';
import mermaid from 'mermaid';

function App() {
  const [step, setStep] = useState('upload'); // upload, mermaid, interactive
  const [imageData, setImageData] = useState(null);
  const [mermaidCode, setMermaidCode] = useState('');
  const [flowData, setFlowData] = useState({ nodes: [], edges: [] });

  const handleImageUpload = async (dataUrl) => {
    setImageData(dataUrl);
    setStep('mermaid');
    
    // Generate Mermaid diagram
    const code = await analyzeSystemDesign(dataUrl);
    setMermaidCode(code);
  };

  const handleConvertToInteractive = () => {
    const data = parseMermaidToReactFlow(mermaidCode);
    setFlowData(data);
    setStep('interactive');
  };

  return (
    <div className="min-h-screen bg-gray-900 text-white">
      <header className="p-4 border-b border-gray-800">
        <h1 className="text-2xl font-bold">System Design Visualizer</h1>
      </header>
      
      <main className="p-8">
        {step === 'upload' && (
          <ImageUploader onImageUpload={handleImageUpload} />
        )}
        
        {step === 'mermaid' && (
          <div className="grid grid-cols-2 gap-4">
            <div>
              <h2 className="text-xl mb-4">Original Image</h2>
              <img src={imageData} alt="Original" className="w-full" />
            </div>
            <div>
              <h2 className="text-xl mb-4">Mermaid Diagram</h2>
              <pre className="bg-gray-800 p-4 rounded overflow-auto">
                {mermaidCode}
              </pre>
              <button 
                onClick={handleConvertToInteractive}
                className="mt-4 px-6 py-2 bg-blue-600 rounded hover:bg-blue-700"
              >
                Convert to Interactive
              </button>
            </div>
          </div>
        )}
        
        {step === 'interactive' && (
          <InteractiveGraph mermaidCode={mermaidCode} />
        )}
      </main>
    </div>
  );
}
```

## Common Patterns

### Copying Mermaid Code to Clipboard

```javascript
import { Copy } from 'lucide-react';

function CopyButton({ text }) {
  const handleCopy = () => {
    navigator.clipboard.writeText(text);
    // Show toast notification
  };

  return (
    <button 
      onClick={handleCopy}
      className="flex items-center gap-2 px-3 py-1 bg-gray-700 rounded hover:bg-gray-600"
    >
      <Copy size={16} />
      Copy Code
    </button>
  );
}
```

### Auto-Layout for React Flow Nodes

```javascript
import dagre from 'dagre';

function getLayoutedElements(nodes, edges) {
  const dagreGraph = new dagre.graphlib.Graph();
  dagreGraph.setDefaultEdgeLabel(() => ({}));
  dagreGraph.setGraph({ rankdir: 'TB' });

  nodes.forEach((node) => {
    dagreGraph.setNode(node.id, { width: 150, height: 50 });
  });

  edges.forEach((edge) => {
    dagreGraph.setEdge(edge.source, edge.target);
  });

  dagre.layout(dagreGraph);

  const layoutedNodes = nodes.map((node) => {
    const nodeWithPosition = dagreGraph.node(node.id);
    return {
      ...node,
      position: {
        x: nodeWithPosition.x - 75,
        y: nodeWithPosition.y - 25
      }
    };
  });

  return { nodes: layoutedNodes, edges };
}
```

## Troubleshooting

### OpenAI API Errors

- **401 Unauthorized**: Check that `VITE_OPENAI_API_KEY` is correctly set in `.env`
- **429 Rate Limit**: Implement retry logic with exponential backoff
- **Image too large**: Resize images before upload (max 20MB)

### Mermaid Parsing Issues

- Ensure generated Mermaid code uses supported syntax (graph TB, graph LR)
- Validate node IDs are alphanumeric without special characters
- Check for balanced brackets in node labels

### React Flow Rendering

- Ensure parent container has explicit height/width
- Import `reactflow/dist/style.css` for proper styling
- Use `fitView` prop to auto-center the graph on mount

### Build Issues

```bash
# Clear cache and reinstall
rm -rf node_modules package-lock.json
npm install

# Check for peer dependency issues
npm list
```

## API Reference

### Main Functions

- `analyzeSystemDesign(imageDataUrl)`: Converts image to Mermaid code
- `parseMermaidToReactFlow(mermaidCode)`: Converts Mermaid to React Flow format
- `getComponentDetails(componentName)`: Gets AI-generated component details
- `getLayoutedElements(nodes, edges)`: Auto-layouts graph nodes

### Environment Variables

- `VITE_OPENAI_API_KEY`: OpenAI API key for AI analysis (optional for mock mode)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in development →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.