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:
-
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.
-
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.
-
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:
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:
#!/bin/bash
# 1. Extract service endpointsfind ./src -name "*.ts" -type f | \ xargs grep -h "@Controller\|@RestController" | \ sed 's/.*class //' | sed 's/ .*//' > /tmp/services.txt
# 2. Generate Mermaid syntaxecho "graph TD" > architecture.mdwhile 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 donedone < /tmp/services.txt
# 3. Output to docsmv architecture.md ./docs/architecture.mdThis script:
- Finds all controllers/services in the codebase
- Generates Mermaid syntax showing service dependencies
- 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:
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"Recommended Workflow
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:
-
Over-detailed diagrams: Including every library and dependency creates unreadable visual noise. Filter aggressively.
-
Missing business context: Pure code analysis misses why services interact. I add annotations to explain the business purpose of each connection.
-
No CI/CD integration: One-off generation means diagrams still go stale. Automation is essential.
-
Wrong abstraction level: I initially showed database tables instead of service boundaries. Use the C4 model to maintain consistent abstraction.
-
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:
- 👨💻 Mermaid MCP
- 👨💻 visual-explainer
- 👨💻 gitnexus
- 👨💻 C4 Model
- 👨💻 Mermaid.js
- 👨💻 PlantUML
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments