Skip to content

How to Auto-Generate System Architecture Diagrams from Code

Problem

When I work with microservices, I face a recurring issue: keeping architecture diagrams in sync with the code. Every time someone adds a service or changes an API endpoint, the documentation becomes outdated. My team spends hours manually updating diagrams in draw.io or Visio, and by the time we finish, the code has changed again.

I tried several approaches to solve this:

  1. Manual diagramming: I created architecture diagrams in draw.io. This took 4-5 hours initially, but after two weeks of code changes, the diagrams were already obsolete.

  2. Static analysis tools: I used tools that scan the codebase and extract dependencies. These produced unreadable “spaghetti diagrams” with hundreds of nodes showing every library import, database connection, and logging call.

  3. One-off diagram generation: I ran scripts to generate diagrams when needed. But without automation, I still forgot to update them.

The core problem: I need a way to automatically generate architecture diagrams from code that (a) captures the right level of abstraction, (b) stays in sync with code changes, and (c) integrates into our CI/CD pipeline.

The Solution: Three-Layer Approach

I solved this by combining three layers: static analysis, LLM-powered abstraction, and automated diagram generation.

Layer 1: Static Analysis

The first step is extracting service boundaries and dependencies from the code. I need to find:

  • API endpoints and services
  • Database connections
  • Message queue dependencies
  • Service-to-service calls

For a typical microservices codebase:

Terminal window
src/
services/
auth-service/
payment-service/
order-service/
notification-service/

Layer 2: LLM-Powered Abstraction

Static analysis alone produces too much detail. I use Claude or GPT-4 to:

  • Identify critical dependencies vs. noise
  • Group related services into domains
  • Apply standard architecture patterns like C4 model
  • Filter out logging, monitoring, and internal utilities

Layer 3: Diagram Generation & CI/CD Integration

The final layer outputs diagrams in a Git-friendly format (Mermaid.js) and integrates into the CI/CD pipeline to update on every commit.

Tool Comparison

I evaluated four approaches:

Mermaid MCP + Claude Code

Best for: Real-time interactive diagram generation

Pros:

  • Conversational diagram creation without leaving the terminal
  • Mermaid syntax is human-readable and version-controlled
  • Iterative refinement through chat
  • No separate diagramming software needed

Cons:

  • Requires manual interaction
  • Best for ad-hoc diagrams vs. bulk generation

Use Case: When I need to ask “What does the payment flow look like?” and get a diagram immediately


visual-explainer

Best for: Automated CLI-based diagram generation

Pros:

  • Command-line tool for automation
  • Can script for CI/CD pipelines
  • Generates multiple diagram types
  • Open-source and extensible

Cons:

  • May require framework-specific configuration
  • Less interactive than LLM-based approaches

Use Case: Generate architecture diagrams on every Git commit


gitnexus

Best for: Git repository visualization and history

Pros:

  • Visualizes Git history alongside code
  • Shows evolution of architecture over time
  • Good for understanding codebase growth

Cons:

  • Focused on Git history vs. current architecture
  • May not capture runtime dependencies

Use Case: Answering “How did our microservices architecture evolve over the last 6 months?”


Cursor + Claude Combo

Best for: IDE-integrated diagram generation

Pros:

  • Generate diagrams without leaving editor
  • Analyzes entire codebase context
  • Iterative refinement through chat

Cons:

  • Requires Cursor IDE
  • Less automated than CLI tools
  • Manual copy-paste to documentation

Use Case: Quick architecture diagrams during development

Implementation Examples

Example 1: Simple Mermaid Diagram (Generated)

Input: Microservices codebase structure

Output (auto-generated Mermaid.js):

graph TD
A[Client] --> B[API Gateway]
B --> C[Auth Service]
B --> D[Order Service]
D --> E[Payment Service]
D --> F[Notification Service]
C -.-> G[(Auth DB)]
D -.-> H[(Orders DB)]
E -.-> I[(Payment DB)]

Example 2: C4 Model with Abstraction

The C4 model provides multiple abstraction levels. Here’s how I apply it:

Level 1: System Context

graph LR
User((User)) --> ECommerce[E-Commerce System]
PaymentProvider((Payment<br/>Provider)) --> ECommerce
ECommerce --> EmailProvider((Email<br/>Provider))

Level 2: Container Diagram

graph TB
WebApp[Web Application] --> API[API Gateway]
MobileApp[Mobile App] --> API
API --> Auth[Auth Service]
API --> Orders[Order Service]
API --> Payments[Payment Service]
Auth --> AuthDB[(Auth DB)]
Orders --> OrdersDB[(Orders DB)]
Payments --> PaymentProvider[Payment Gateway API]

Example 3: Custom Script Approach

For more control, I wrote a custom script:

generate-diagrams.sh
#!/bin/bash
# 1. Extract service endpoints
find ./src -name "*.ts" -type f | \
xargs grep -h "@Controller\|@RestController" | \
sed 's/.*class //' | sed 's/ .*//' > /tmp/services.txt
# 2. Generate Mermaid syntax
echo "graph TD" > architecture.md
while IFS= read -r service; do
echo " $service [$service]" >> architecture.md
# Find dependencies (simplified example)
grep -r "import.*$service" ./src | \
cut -d: -f1 | \
xargs basename | \
sed 's/\.ts$//' | \
sort -u | \
while read dep; do
echo " $dep --> $service" >> architecture.md
done
done < /tmp/services.txt
# 3. Output to docs
mv architecture.md ./docs/architecture.md

This script:

  1. Finds all controllers/services in the codebase
  2. Generates Mermaid syntax showing service dependencies
  3. Outputs the diagram to a documentation folder

CI/CD Integration

The key to keeping diagrams up-to-date is integrating generation into the CI/CD pipeline. Here’s a GitHub Actions workflow:

.github/workflows/diagrams.yml
name: Generate Architecture Diagrams
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
generate-diagrams:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install visual-explainer
run: npm install -g @nicobailon/visual-explainer
- name: Generate Mermaid diagrams
run: |
visual-explainer parse --src ./src \
--output ./docs/architecture.md \
--format mermaid \
--level service
- name: Commit diagrams
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git add ./docs/architecture.md
git diff --quiet && git diff --staged --quiet || git commit -m "chore: update architecture diagrams [skip ci]"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

Alternative: Mermaid MCP in Pipeline

- name: Generate diagrams with Claude Code
run: |
claude-code --mcp mermaid \
"Generate architecture diagram for services in ./src, output to ./docs/diagrams.md"

When I help teams set this up, I follow a phased approach:

Week 1: Manual Mermaid Generation

  • Use Claude Code + Mermaid MCP to generate initial diagrams
  • Identify critical services and dependencies
  • Establish diagram conventions (C4 model recommended)

Week 2: Automated Static Analysis

  • Integrate visual-explainer or gitnexus
  • Configure filters to exclude noise (logging, monitoring)
  • Generate base Mermaid/PlantUML files

Week 3: CI/CD Integration

  • Add diagram generation to GitHub Actions/GitLab CI
  • Commit diagram files to repository
  • Set up auto-rendering in documentation platform

Ongoing: Manual Curation

  • Review generated diagrams in PRs
  • Add business context annotations
  • Refine abstraction level

Common Mistakes

I made these mistakes so you don’t have to:

  1. Over-detailed diagrams: Including every library and dependency creates unreadable visual noise. Filter aggressively.

  2. Missing business context: Pure code analysis misses why services interact. I add annotations to explain the business purpose of each connection.

  3. No CI/CD integration: One-off generation means diagrams still go stale. Automation is essential.

  4. Wrong abstraction level: I initially showed database tables instead of service boundaries. Use the C4 model to maintain consistent abstraction.

  5. Ignoring human review: Auto-generated diagrams need curation. I always review before committing.

The Reason

The key reason this approach works is that it separates extraction (static analysis) from abstraction (LLM-powered filtering) from visualization (Mermaid/PlantUML). Each layer does what it does best:

  • Static analysis extracts accurate dependencies
  • LLMs apply human-like abstraction to filter noise
  • Diagram generators produce version-controlled, Git-friendly output

Summary

In this post, I showed how to auto-generate system architecture diagrams from code using a three-layer approach: static analysis, LLM-powered abstraction, and CI/CD automation. The key point is combining tools like Mermaid MCP, visual-explainer, and gitnexus to generate diagrams that stay in sync with code changes.

I use Mermaid.js for Git-friendly diagrams, integrate generation into the pipeline, and maintain human curation for business context. This eliminates manual diagram maintenance while keeping documentation accurate.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments