Free & open source — no account required

v1.2.5-PRICING-19
Web & Frontend • Engineering Documentation

Mermaid.js Mastery: Visualizing Data Structures

This technical guide provides an in-depth analysis of the json to mermaid engine, best practices for implementation, and data security standards.

JSON to Mermaid: ER Diagrams, Class Diagrams, and Sequence Diagrams from Data

Mermaid is a text-based diagramming tool that renders directly in GitHub Markdown, GitLab, Notion, Docusaurus, and VS Code. Converting JSON to Mermaid gives you diagrams that live in version control, update automatically when the schema changes, and require no design tool. The key insight is that different JSON shapes map to different Mermaid diagram types: a JSON schema with nested objects maps to a class diagram or ER diagram; an array of API interactions maps to a sequence diagram; a dependency graph maps to a flowchart. Choosing the right diagram type matters more than the syntax.

Live Example: JSON Schema → ER Diagram

// Input JSON (API schema for an e-commerce system)
{
  "Order": {
    "id": "uuid",
    "customer_id": "uuid",
    "status": "enum",
    "total": "decimal",
    "created_at": "datetime",
    "items": [{ "product_id": "uuid", "quantity": "int", "unit_price": "decimal" }]
  },
  "Customer": {
    "id": "uuid",
    "email": "string",
    "name": "string",
    "tier": "enum"
  },
  "Product": {
    "id": "uuid",
    "sku": "string",
    "name": "string",
    "price": "decimal",
    "stock": "int"
  }
}

// Generated Mermaid ER Diagram
erDiagram
    Customer {
        uuid id PK
        string email UK
        string name
        string tier "starter|professional|enterprise"
    }
    Order {
        uuid id PK
        uuid customer_id FK
        string status "pending|confirmed|shipped|delivered"
        decimal total
        datetime created_at
    }
    OrderItem {
        uuid order_id FK
        uuid product_id FK
        int quantity
        decimal unit_price
    }
    Product {
        uuid id PK
        string sku UK
        string name
        decimal price
        int stock
    }

    Customer ||--o{ Order        : "places"
    Order    ||--|{ OrderItem    : "contains"
    Product  ||--o{ OrderItem   : "referenced by"

Render in a GitHub README using a fenced code block with the mermaid language tag. The ER diagram uses crow's foot notation: || = exactly one, o{ = zero or many, |{ = one or many.

JSON Object → Class Diagram

// Input JSON (TypeScript-like type hierarchy)
{
  "BaseEntity": { "id": "string", "createdAt": "Date", "updatedAt": "Date" },
  "User": { "extends": "BaseEntity", "email": "string", "role": "UserRole" },
  "AdminUser": { "extends": "User", "permissions": "string[]", "canBan": "boolean" },
  "UserRole": { "enum": ["VIEWER", "EDITOR", "ADMIN"] }
}

// Generated Mermaid Class Diagram
classDiagram
    class BaseEntity {
        +String id
        +Date createdAt
        +Date updatedAt
    }
    class User {
        +String email
        +UserRole role
        +validate() Boolean
        +toJSON() Object
    }
    class AdminUser {
        +String[] permissions
        +Boolean canBan
        +grantPermission(perm) void
        +revokePermission(perm) void
    }
    class UserRole {
        <<enumeration>>
        VIEWER
        EDITOR
        ADMIN
    }

    BaseEntity <|-- User       : extends
    User       <|-- AdminUser  : extends
    User        --> UserRole    : uses

API Interactions → Sequence Diagram

// Input JSON (API interaction log)
[
  { "from": "Browser",  "to": "NextAPI",   "message": "POST /login",              "type": "request"  },
  { "from": "NextAPI",  "to": "AuthSvc",   "message": "validateCredentials()",     "type": "call"     },
  { "from": "AuthSvc",  "to": "Database",  "message": "SELECT * FROM users",       "type": "query"    },
  { "from": "Database", "to": "AuthSvc",   "message": "user record",               "type": "response" },
  { "from": "AuthSvc",  "to": "NextAPI",   "message": "JWT token",                 "type": "response" },
  { "from": "NextAPI",  "to": "Browser",   "message": "200 OK {token}",            "type": "response" }
]

// Generated Mermaid Sequence Diagram
sequenceDiagram
    actor Browser
    participant NextAPI as Next.js API
    participant AuthSvc as Auth Service
    participant Database

    Browser   ->>  NextAPI:   POST /login
    activate NextAPI

    NextAPI   ->>  AuthSvc:   validateCredentials()
    activate AuthSvc

    AuthSvc   ->>  Database:  SELECT * FROM users WHERE email=?
    activate Database
    Database  -->> AuthSvc:   user record
    deactivate Database

    AuthSvc   -->> NextAPI:   JWT token
    deactivate AuthSvc

    NextAPI   -->> Browser:   200 OK { token }
    deactivate NextAPI

    Note over AuthSvc,Database: Password verified with bcrypt

Dependency Graph → Flowchart

// Input JSON (microservice dependencies)
{
  "services": [
    { "name": "WebApp",     "depends_on": ["ApiGateway"] },
    { "name": "ApiGateway", "depends_on": ["UserSvc", "OrderSvc", "AuthSvc"] },
    { "name": "UserSvc",    "depends_on": ["Postgres", "Redis"] },
    { "name": "OrderSvc",   "depends_on": ["Postgres", "MessageQueue"] },
    { "name": "AuthSvc",    "depends_on": ["Redis"] }
  ]
}

// Generated Mermaid Flowchart
flowchart TD
    subgraph Frontend
        WebApp
    end

    subgraph Gateway
        ApiGateway
    end

    subgraph Services
        UserSvc
        OrderSvc
        AuthSvc
    end

    subgraph Infrastructure
        Postgres[(PostgreSQL)]
        Redis[(Redis Cache)]
        MessageQueue{{Message Queue}}
    end

    WebApp     --> ApiGateway
    ApiGateway --> UserSvc
    ApiGateway --> OrderSvc
    ApiGateway --> AuthSvc
    UserSvc    --> Postgres
    UserSvc    --> Redis
    OrderSvc   --> Postgres
    OrderSvc   --> MessageQueue
    AuthSvc    --> Redis

    style WebApp     fill:#e1f5fe
    style ApiGateway fill:#fff3e0
    style Postgres   fill:#f3e5f5
    style Redis      fill:#fce4ec

State Machine from JSON Config

// Input JSON (order status state machine)
{
  "states": ["pending", "confirmed", "processing", "shipped", "delivered", "cancelled"],
  "transitions": [
    { "from": "pending",    "to": "confirmed",  "on": "confirm_payment" },
    { "from": "confirmed",  "to": "processing", "on": "start_processing" },
    { "from": "confirmed",  "to": "cancelled",  "on": "cancel" },
    { "from": "processing", "to": "shipped",    "on": "ship" },
    { "from": "shipped",    "to": "delivered",  "on": "deliver" },
    { "from": "shipped",    "to": "cancelled",  "on": "return_requested" }
  ]
}

// Generated Mermaid State Diagram
stateDiagram-v2
    [*] --> pending : new order

    pending    --> confirmed   : confirm_payment
    confirmed  --> processing  : start_processing
    confirmed  --> cancelled   : cancel
    processing --> shipped     : ship
    shipped    --> delivered   : deliver
    shipped    --> cancelled   : return_requested

    delivered --> [*]
    cancelled --> [*]

    note right of processing : triggers warehouse notification
    note right of shipped    : sends tracking email

Rendering Mermaid in Different Contexts

// GitHub/GitLab Markdown — native rendering
```mermaid
erDiagram
    User ||--o{ Order : "places"
```

// Docusaurus (MDX) — built-in support via @docusaurus/theme-mermaid
// docusaurus.config.js
module.exports = {
  themes: ['@docusaurus/theme-mermaid'],
  markdown: { mermaid: true },
};

// Programmatic rendering with @mermaid-js/mermaid-cli
npx mmdc -i diagram.mmd -o diagram.svg -t dark
npx mmdc -i diagram.mmd -o diagram.png --width 1200 --height 800

// Node.js: generate Mermaid string from JSON
function jsonToErDiagram(schema: Record>): string {
  const lines = ['erDiagram'];
  for (const [entity, fields] of Object.entries(schema)) {
    lines.push(`    ${entity} {`);
    for (const [field, type] of Object.entries(fields)) {
      lines.push(`        ${type} ${field}`);
    }
    lines.push('    }');
  }
  return lines.join('\n');
}

Best Practices for Production

  • Choose diagram type based on JSON shape: Objects with relationships → ER diagram. Type hierarchy with methods → class diagram. API calls in order → sequence diagram. Service dependencies → flowchart. State transitions → state diagram. Don't force JSON into the wrong diagram type.
  • Limit diagram scope: A Mermaid diagram with more than 15-20 nodes becomes hard to read. For large JSON schemas, generate separate diagrams per bounded context, or generate an overview diagram with only top-level entities and link to detailed diagrams.
  • Use subgraphs in flowcharts: Group related nodes into subgraph blocks to add visual hierarchy. This is especially useful for microservice architectures where services cluster into frontend, backend, and infrastructure layers.
  • Commit generated Mermaid alongside source JSON: Keep the .mmd files in the same directory as the JSON schema they were generated from. Add a script to regenerate diagrams when schemas change. Reviewers can diff the text diagram in PRs.

FAQ

Q: What Mermaid diagram type best represents a JSON Schema?
A: ER diagram (erDiagram) for data models with relationships and foreign keys. Class diagram (classDiagram) for object hierarchies with methods and inheritance. For a flat JSON object with no relationships, a simple flowchart showing key → value structure is often more readable than forcing it into an ER diagram.

Q: Can I use Mermaid for API documentation?
A: Yes — sequence diagrams are excellent for documenting API call flows, authentication flows, and webhook interactions. Combine Mermaid diagrams with OpenAPI/Swagger spec for comprehensive documentation: OpenAPI for endpoints, Mermaid sequences for flows.

Q: How do I handle long labels in Mermaid?
A: Use quoted strings for labels with spaces or special characters: A["Long Label Text"]. For very long labels, use
inside quotes for line breaks. Alternatively, use short node IDs and a legend table in the surrounding Markdown.

Q: Does Mermaid support themes?
A: Yes — built-in themes: default, dark, forest, neutral, base (customizable). Set via the %%{init: {'theme': 'dark'}}%% directive at the top of the diagram, or globally in the Mermaid initialize() call.

Developer FAQ

Is the processing local-only?

Absolutely. TypeMorph operates entirely within your browser's sandbox. We use Web Workers for high-performance computation without ever transmitting your JSON, SQL, or API data to a remote server.

Can I use this for enterprise projects?

Yes. The tool is designed for professional software engineers who require GDPR compliance and data privacy. It is trusted by developers at top-tier startups and financial institutions.