🎨 Frontend Beginner ⏱️ 10 min

Creating Technical Diagrams with Mermaid

A comprehensive guide to using Mermaid.js for creating architecture diagrams, flowcharts, sequence diagrams, and more in your technical documentation.

By Victor Robin

Introduction

Technical documentation often requires visual representations of complex systems. While tools like Lucidchart or draw.io work well, they create binary files that are difficult to version control and review. Mermaid.js solves this problem by rendering diagrams from plain text definitions.

Why Mermaid?

  • Version Control Friendly: Diagrams are plain text, so changes show up in Git diffs
  • Live in Documentation: No separate files to manage or links to break
  • Quick Iteration: Update the text, see the result immediately
  • Consistent Styling: Automatic theming that matches your site’s design

Getting Started

In MDX files, you can create diagrams using fenced code blocks with the mermaid language identifier:

```mermaid
graph LR
    A[Start] --> B[Process]
    B --> C[End]
```

This renders as:

graph LR
    A[Start] --> B[Process]
    B --> C[End]

Flowcharts

Flowcharts are the most versatile diagram type. They support various node shapes, connection styles, and subgraphs.

Basic Flowchart

graph TD
    A[User Request] --> B{Authenticated?}
    B -->|Yes| C[Process Request]
    B -->|No| D[Redirect to Login]
    C --> E[Return Response]
    D --> F[Show Login Form]

Node Shapes

Mermaid supports different shapes to convey meaning:

graph LR
    A[Rectangle] --> B(Rounded)
    B --> C{Diamond}
    C --> D([Stadium])
    D --> E[[Subroutine]]
    E --> F[(Database)]
    F --> G((Circle))
ShapeSyntaxUse Case
Rectangle[text]Standard process step
Rounded(text)Start/end points
Diamond{text}Decision points
Stadium([text])Events or triggers
Subroutine[[text]]Subprocess call
Cylinder[(text)]Database or storage
Circle((text))Connection point

Subgraphs for Organization

For complex systems, subgraphs help group related components:

graph TB
    subgraph Frontend ["🖥️ Frontend Layer"]
        UI[Blazor Web App]
        Components[UI Components]
    end
    
    subgraph Backend ["⚙️ Backend Services"]
        API[FastEndpoints API]
        Workers[Background Workers]
    end
    
    subgraph Data ["💾 Data Layer"]
        DB[(PostgreSQL)]
        Vector[(Qdrant)]
        Cache[(Redis)]
    end
    
    UI --> API
    Components --> UI
    API --> DB
    API --> Vector
    Workers --> Cache
    Workers --> DB

Sequence Diagrams

Sequence diagrams are perfect for showing interactions between services over time.

Basic Sequence

sequenceDiagram
    participant U as User
    participant W as Web App
    participant A as API
    participant D as Database
    
    U->>W: Upload Document
    W->>A: POST /documents
    A->>D: Store Metadata
    D-->>A: Document ID
    A-->>W: 201 Created
    W-->>U: Show Success

Advanced Interactions

sequenceDiagram
    participant Client
    participant API
    participant NATS
    participant OCR Worker
    participant Qdrant
    
    Client->>+API: Upload PDF
    API->>NATS: Publish document.uploaded
    API-->>-Client: 202 Accepted
    
    NATS->>+OCR Worker: document.uploaded
    OCR Worker->>OCR Worker: Extract Text
    OCR Worker->>NATS: Publish document.processed
    OCR Worker->>-Qdrant: Store Embeddings
    
    Note over Client,Qdrant: Async processing flow

Activation and Loops

sequenceDiagram
    participant C as Client
    participant S as Server
    
    C->>+S: Request with Retry
    
    loop Retry Logic
        S->>S: Process Request
        alt Success
            S-->>C: 200 OK
        else Failure
            S-->>C: 500 Error
            C->>S: Retry Request
        end
    end
    
    deactivate S

Class Diagrams

For documenting domain models and object relationships:

classDiagram
    class Document {
        +BlueRobinId Id
        +string Title
        +DocumentStatus Status
        +Upload()
        +Process()
    }
    
    class Archive {
        +BlueRobinId Id
        +string OwnerId
        +List~Document~ Documents
        +AddDocument()
    }
    
    class User {
        +BlueRobinId Id
        +string ExternalId
        +Archive Archive
    }
    
    User "1" --> "1" Archive : owns
    Archive "1" --> "*" Document : contains

State Diagrams

State diagrams show the lifecycle of an entity:

stateDiagram-v2
    [*] --> Uploaded: User uploads
    
    Uploaded --> Processing: OCR starts
    Processing --> Processed: OCR complete
    Processing --> Failed: Error
    
    Processed --> Embedding: Generate vectors
    Embedding --> Indexed: Store in Qdrant
    Embedding --> Failed: Error
    
    Indexed --> [*]: Ready for search
    
    Failed --> Uploaded: Retry

Entity Relationship Diagrams

For database schema documentation:

erDiagram
    USER ||--o{ ARCHIVE : owns
    ARCHIVE ||--|{ DOCUMENT : contains
    DOCUMENT ||--o{ CHUNK : "split into"
    CHUNK ||--|| EMBEDDING : has
    
    USER {
        uuid id PK
        string external_id
        string bluerobin_id UK
        timestamp created_at
    }
    
    DOCUMENT {
        uuid id PK
        uuid archive_id FK
        string title
        string status
        timestamp uploaded_at
    }
    
    EMBEDDING {
        uuid id PK
        uuid chunk_id FK
        vector embedding
    }

Architecture Diagrams (C4 Style)

For high-level system views, combine subgraphs with styling:

graph TB
    subgraph External ["External Systems"]
        Auth[Authelia SSO]
        MinIO[MinIO Storage]
    end
    
    subgraph BlueRobin ["BlueRobin System"]
        subgraph Web ["Web Tier"]
            Blazor[Blazor Server]
        end
        
        subgraph Services ["Service Tier"]
            API[REST API]
            Workers[Workers]
        end
        
        subgraph Data ["Data Tier"]
            PG[(PostgreSQL)]
            Qdrant[(Qdrant)]
            NATS{{NATS JetStream}}
        end
    end
    
    Blazor --> Auth
    Blazor --> API
    API --> PG
    API --> NATS
    Workers --> NATS
    Workers --> Qdrant
    Workers --> MinIO

Gantt Charts

For project timelines and planning:

gantt
    title BlueRobin Development Timeline
    dateFormat YYYY-MM-DD
    
    section Infrastructure
    K3s Setup           :done, infra1, 2024-01-01, 14d
    GitOps Config       :done, infra2, after infra1, 7d
    
    section Core Features
    Document Upload     :done, core1, 2024-01-15, 14d
    OCR Pipeline        :active, core2, after core1, 21d
    Search API          :core3, after core2, 14d
    
    section AI Features
    RAG Implementation  :ai1, after core3, 28d
    Agent Integration   :ai2, after ai1, 21d

Pie Charts

For simple data visualization:

pie showData
    title Document Types in Archive
    "PDF" : 45
    "Images" : 25
    "Word Docs" : 15
    "Other" : 15

Best Practices

Styling Tips

You can add custom styling to nodes:

graph LR
    A[Critical]:::critical --> B[Warning]:::warning --> C[Info]:::info
    
    classDef critical fill:#ef4444,color:white
    classDef warning fill:#f59e0b,color:white
    classDef info fill:#3b82f6,color:white

Common Patterns

Request-Response Flow

sequenceDiagram
    participant C as Client
    participant G as API Gateway
    participant S as Service
    participant D as Database
    
    C->>G: HTTP Request
    G->>G: Validate Token
    G->>S: Forward Request
    S->>D: Query Data
    D-->>S: Results
    S-->>G: Response
    G-->>C: HTTP Response

Event-Driven Architecture

graph LR
    subgraph Producers
        A[API]
        B[Workers]
    end
    
    subgraph MessageBroker ["NATS JetStream"]
        Q1{{Stream: documents}}
        Q2{{Stream: notifications}}
    end
    
    subgraph Consumers
        C[OCR Worker]
        D[Embedding Worker]
        E[Notification Service]
    end
    
    A --> Q1
    B --> Q2
    Q1 --> C
    Q1 --> D
    Q2 --> E

Conclusion

Mermaid transforms technical documentation from static text into living visual documentation. By embedding diagrams directly in your MDX files, you ensure they stay in sync with the code and can be reviewed alongside it.

Key Takeaways:

  • Use flowcharts for architecture and process flows
  • Use sequence diagrams for service interactions
  • Use class/ER diagrams for domain modeling
  • Use state diagrams for entity lifecycles
  • Keep diagrams focused and use subgraphs for complex systems

Further Reading