Detect hidden complexity in your Mermaid diagrams
A complexity analyzer and readability linter for Mermaid diagrams. Like sonar detects underwater obstacles, Mermaid-Sonar detects hidden complexity issues before they cause readability problems.
Mermaid diagrams are great for documentation, but complex diagrams can hurt more than they help. Mermaid-Sonar analyzes your diagrams using:
- Graph theory metrics (density, branching, connectivity)
- Cognitive load research (50/100 node thresholds)
- Mermaid best practices (100 connection O(n²) limit)
- Layout intelligence (LR vs TD recommendations)
- Viewport readability (width/height constraints for optimal viewing)
- ✅ Multi-diagram type support - Flowcharts, graphs, state diagrams, class diagrams, and sequence diagrams
- ✅ Syntax validation - Detects Mermaid syntax errors before rendering
- ✅ Research-backed thresholds - Not arbitrary limits
- ✅ Actionable recommendations - Not just "too complex"
- ✅ Multiple output formats - Terminal, JSON, Markdown, GitHub Actions
- ✅ Zero rendering dependencies - Pure static analysis
- ✅ Fast - Analyzes hundreds of diagrams in seconds
- ✅ Configurable - Adjust thresholds to your needs
# Install
npm install -g mermaid-sonar
# Analyze diagrams in your docs
mermaid-sonar docs/**/*.md
# With custom config
mermaid-sonar --config .sonarrc.json docs/Mermaid-Sonar validates Mermaid syntax using the official Mermaid parser, catching errors before they cause rendering failures:
Invalid syntax example:
<!-- Invalid syntax - missing arrow -->
```mermaid
graph TD
A B
```Detected error:
❌ docs/example.md:3
Syntax error: Parse error on line 2:
A B
---^
Expecting 'SEMI', 'NEWLINE', 'EOF', 'AMP', 'START_LINK', 'LINK', got 'ALPHA'
→ Fix the Mermaid syntax or consult the Mermaid documentation
Syntax validation runs automatically on all diagrams and reports errors with:
- Line numbers: Exact location of the syntax error
- Error context: What the parser expected vs. what it found
- Exit code: Non-zero exit code (1) for CI/CD integration
This ensures your diagrams are syntactically correct before analyzing complexity.
Analyzing Mermaid diagrams...
❌ docs/architecture.md:42
Wide tree diagram with 12 parallel branches (>8 max)
→ Consider using 'graph LR' or split into multiple diagrams
⚠️ docs/workflow.md:156
Complex diagram with 85 nodes
→ Consider breaking into focused sub-diagrams
✓ docs/overview.md:15 - Valid and readable
Summary:
Total diagrams: 23
Valid & Readable: 20
Warnings: 2
Errors: 1
# Global installation
npm install -g mermaid-sonar
# Project dependency
npm install --save-dev mermaid-sonar
# Using npx (no installation)
npx mermaid-sonar docs/# Analyze specific files
mermaid-sonar README.md docs/architecture.md
# Glob patterns
mermaid-sonar "docs/**/*.md"
# Output formats
mermaid-sonar --format json docs/ # JSON output
mermaid-sonar --format markdown docs/ # Markdown report
# With config file
mermaid-sonar --config .sonarrc.json docs/import { analyzeDiagrams } from 'mermaid-sonar';
const results = await analyzeDiagrams(['docs/**/*.md']);
console.log(`Found ${results.issues.length} issues`);When using --format json, the output follows this TypeScript schema:
interface JSONOutput {
version: string;
summary: {
filesAnalyzed: number;
diagramsAnalyzed: number;
totalIssues: number;
errorCount: number;
warningCount: number;
infoCount: number;
duration: number; // milliseconds
};
results: Array<{
diagram: {
content: string; // Raw Mermaid code
startLine: number; // 1-indexed line number
filePath: string; // Source file path
type: 'flowchart' | 'graph' | 'state' | 'class' | 'sequenceDiagram' | 'unknown';
};
metrics: {
nodeCount: number;
edgeCount: number;
graphDensity: number; // edges / (nodes × (nodes-1))
maxBranchWidth: number; // Max children from any node
averageDegree: number; // Avg connections per node
};
issues: Array<{
rule: string; // Rule identifier
severity: 'error' | 'warning' | 'info';
message: string; // Human-readable message
filePath: string; // Source file path
line: number; // Line number
suggestion?: string; // Fix suggestion
citation?: string; // Research citation URL
}>;
}>;
}Example JSON output:
{
"version": "1.4.0",
"summary": {
"filesAnalyzed": 3,
"diagramsAnalyzed": 5,
"totalIssues": 2,
"errorCount": 1,
"warningCount": 1,
"infoCount": 0,
"duration": 42
},
"results": [
{
"diagram": {
"content": "graph TD\n A --> B\n ...",
"startLine": 42,
"filePath": "docs/architecture.md",
"type": "graph"
},
"metrics": {
"nodeCount": 55,
"edgeCount": 78,
"graphDensity": 0.026,
"maxBranchWidth": 12,
"averageDegree": 2.84
},
"issues": [
{
"rule": "max-branch-width",
"severity": "error",
"message": "Wide tree diagram with 12 parallel branches (>8 max)",
"filePath": "docs/architecture.md",
"line": 42,
"suggestion": "Consider using 'graph LR' or split into multiple diagrams",
"citation": "https://example.com/visual-hierarchy-research"
}
]
}
]
}mermaid-sonar [options] <files...><files...>- Files, directories, or glob patterns to analyze (required)- Examples:
README.md,docs/,"src/**/*.md" - Supports multiple arguments:
docs/ README.md examples/
- Examples:
-
-f, --format <format>- Output format (default:console)- console: Colorized terminal output with detailed metrics
- json: Machine-readable JSON for CI/CD integration
- markdown: Formatted markdown report with tables
- github: GitHub-flavored markdown with collapsible sections
- junit: JUnit XML format for test result integration
-
-o, --output <file>- Write output to file instead of stdout- Example:
--output report.json - Works with all formats
- Example:
-
-q, --quiet- Suppress non-error output- Only shows errors, no progress or summary
- Useful for silent CI/CD runs
-
-v, --verbose- Show detailed analysis information- Displays file counts and processing details
- Cannot be used with
--quiet
-
-r, --recursive- Recursively scan directories- Example:
mermaid-sonar -r docs/scans all subdirectories - Without this flag, only top-level files are analyzed
- Example:
-
-s, --strict- Treat warnings as errors- Exit code 1 if any warnings are found
- Useful for enforcing zero-warning policies in CI
-
--max-warnings <number>- Maximum warnings before failing- Example:
--max-warnings 5 - Exit code 1 if warnings exceed this threshold
- Requires numeric value
- Example:
-
--no-rules- Disable rule validation (only show metrics)- Shows raw metrics without applying rules
- Useful for understanding diagram characteristics
-
--viewport-profile <name>- Use built-in viewport profile- default: 2500×2000px (standard browser viewport)
- mkdocs: 800×1500px (MkDocs with sidebar)
- docusaurus: 900×1500px (Docusaurus framework)
- github: 1000×1800px (GitHub markdown)
- mobile: 400×800px (mobile devices)
- Example:
--viewport-profile mkdocs
-
--max-width <pixels>- Maximum diagram width (hard limit)- Diagrams exceeding this value will generate ERROR-level issues
- Overrides profile width if both specified
- Example:
--max-width 1200
-
--max-height <pixels>- Maximum diagram height (hard limit)- Diagrams exceeding this value will generate ERROR-level issues
- Overrides profile height if both specified
- Example:
--max-height 1000
-c, --config <path>- Path to configuration file- Example:
--config custom-config.json - Overrides automatic config discovery
- See Configuration section
- Example:
Mermaid-Sonar uses standard exit codes for CI/CD integration:
-
0: Success - No errors found
- All diagrams analyzed successfully
- No errors, or only warnings (without
--strict)
-
1: Validation failure - Errors or warnings with
--strict- Found errors in one or more diagrams
- Found warnings when
--strictis enabled - Exceeded
--max-warningsthreshold
-
2: Execution failure - Tool error
- No files found matching pattern
- Invalid configuration file
- File system errors or parsing failures
# Analyze single file
mermaid-sonar README.md
# Analyze multiple files
mermaid-sonar README.md docs/architecture.md
# Analyze directory (non-recursive)
mermaid-sonar docs/
# Analyze directory recursively
mermaid-sonar -r docs/
# Glob patterns (quote to prevent shell expansion)
mermaid-sonar "docs/**/*.md"
mermaid-sonar "src/**/*.{md,mdx}"# JSON output for CI/CD
mermaid-sonar --format json docs/ > report.json
# Markdown report
mermaid-sonar --format markdown -o report.md docs/
# GitHub-flavored markdown
mermaid-sonar --format github docs/
# JUnit XML for test integration
mermaid-sonar --format junit -o junit.xml docs/For detailed examples and use cases for each format, see the Output Formats Guide.
# Strict mode - fail on any warning
mermaid-sonar --strict docs/
# Allow up to 5 warnings
mermaid-sonar --max-warnings 5 docs/
# Quiet mode for CI logs
mermaid-sonar --quiet --format json -o report.json docs/
# Verbose mode for debugging
mermaid-sonar --verbose docs/# Use custom config
mermaid-sonar --config .sonarrc.json docs/
# Disable rules, show only metrics
mermaid-sonar --no-rules docs/# Use MkDocs profile for documentation sites
mermaid-sonar --viewport-profile mkdocs docs/
# Use GitHub profile for README files
mermaid-sonar --viewport-profile github README.md
# Custom width and height limits
mermaid-sonar --max-width 1200 --max-height 1600 docs/
# Combine profile with custom overrides (CLI overrides profile)
mermaid-sonar --viewport-profile mkdocs --max-height 2000 docs/
# Use mobile profile for responsive design validation
mermaid-sonar --viewport-profile mobile docs/name: Lint Diagrams
on: [pull_request]
jobs:
lint-diagrams:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npx mermaid-sonar docs/# .gitlab-ci.yml
lint-diagrams:
stage: test
image: node:20
script:
- npx mermaid-sonar --format junit -o junit.xml docs/
artifacts:
when: always
reports:
junit: junit.xml// Jenkinsfile
pipeline {
agent any
stages {
stage('Lint Diagrams') {
steps {
sh 'npx mermaid-sonar --format junit -o junit.xml docs/'
junit 'junit.xml'
}
}
}
}// .vscode/tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "Lint Mermaid Diagrams",
"type": "shell",
"command": "npx mermaid-sonar --format console docs/",
"problemMatcher": [],
"group": {
"kind": "test",
"isDefault": true
}
},
{
"label": "Generate Diagram Report",
"type": "shell",
"command": "npx mermaid-sonar --format markdown -o diagram-report.md docs/",
"problemMatcher": []
}
]
}# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: mermaid-sonar
name: Mermaid Complexity Check
entry: npx mermaid-sonar
language: system
files: \\.md$Create .sonarrc.json, .sonarrc.yaml, or add to package.json:
{
"mermaid-sonar": {
"rules": {
"max-nodes": {
"enabled": true,
"high-density": 50,
"low-density": 100,
"severity": "error"
},
"max-edges": {
"enabled": true,
"limit": 100,
"severity": "warning"
},
"graph-density": {
"enabled": true,
"threshold": 0.3,
"severity": "warning"
},
"cyclomatic-complexity": {
"enabled": true,
"limit": 15,
"severity": "warning"
}
}
}
}| Rule | Default | Research Basis |
|---|---|---|
max-nodes |
50/100 | Cognitive load research |
max-edges |
100 | Mermaid O(n²) mkdocs |
graph-density |
0.3 | Graph theory best practices |
cyclomatic-complexity |
15 | Software engineering standards |
max-branch-width |
8 | Visual hierarchy research |
layout-hint |
enabled | Mermaid layout best practices |
horizontal-chain-too-long |
LR: 8, TD: 12 | Viewport width constraints & scrolling UX |
horizontal-width-readability |
info: 1500px, warning: 2000px, error: 2500px | Viewport width limits & readability |
vertical-height-readability |
info: 800px, warning: 1200px, error: 2000px | Viewport height limits & readability |
See docs/rules.md for detailed rule documentation.
All thresholds are based on published research:
- Node limits: "Scalability of Network Visualisation from a Cognitive Load Perspective" - Study showing 50-node limit for high-density graphs
- Connection limit: Mermaid official blog - O(n²) complexity warning
- Cyclomatic complexity: McCabe's original research on code complexity
# Setup
git clone https://github.com/iepathos/mermaid-sonar.git
cd mermaid-sonar
npm install
# Development
npm run dev # Watch mode
npm test # Run tests
npm run build # Build for production
npm run typecheck # Type checking
# Before commit
npm run format # Format code
npm run lint # Lint code
npm test # Run testsContributions welcome! Please read CONTRIBUTING.md first.
MIT © Glen Baker [email protected]
- Built on research from cognitive load and graph theory studies
- Inspired by the Mermaid.js community
- Initial implementation based on internal diagram validation tools
Like sonar reveals what's hidden underwater, Mermaid-Sonar reveals hidden complexity in your diagrams 🌊