dependency-graph-analyzer
v1.0.1
Published
Universal dependency graph analyzer with cycle detection, Tarjan's algorithm, and GraphViz visualization
Maintainers
Readme
Dependency Graph Analyzer
Universal dependency graph analysis with cycle detection, Tarjan's algorithm, and GraphViz visualization
Live Demo • Installation • Quick Start • API Reference • Examples
🎯 Overview
Dependency Graph Analyzer is a powerful TypeScript library and GraphQL API that analyzes dependency graphs to detect cycles, find strongly connected components, and visualize relationships.
It answers the questions:
- ✅ Are there circular dependencies in my system?
- ✅ What's the correct build/install order?
- ✅ Which packages are most critical?
- ✅ How do my components relate to each other?
Why This Tool?
- Tarjan's Algorithm — Find strongly connected components in linear time O(V+E)
- Cycle Detection — Identify circular dependencies with severity levels
- Topological Sort — Get valid dependency ordering
- GraphViz Integration — Beautiful SVG visualizations with highlighted cycles
- Universal — Works for software packages, microservices, courses, teams, or any dependency system
- GraphQL API — Query exactly what you need, nothing more
✨ Features
| Feature | Description | |---------|-------------| | Cycle Detection | Finds all circular dependencies with ERROR/WARNING severity | | Tarjan's Algorithm | Computes strongly connected components efficiently | | Topological Sorting | Returns valid dependency order (if no cycles exist) | | Critical Package Analysis | Ranks packages by number of dependents | | GraphViz Visualization | Generates DOT format and SVG images | | GraphQL API | Flexible query interface - request only what you need | | TypeScript | Full type safety and IntelliSense support | | Live API | Production-ready endpoint at https://dep-graph-analyzer.shehan.io/graphql |
📦 Installation
Option 1: Use the Live API (No Installation Required!)
Simply send GraphQL queries to:
https://dep-graph-analyzer.shehan.io/graphqlQuick Test:
curl -X POST https://dep-graph-analyzer.shehan.io/graphql \
-H "Content-Type: application/json" \
-d '{"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"], \\\"B\\\": [\\\"C\\\"]}\") { stats { totalNodes hasCycles } } }"}'Option 2: Install via NPM ✅
npm install dependency-graph-analyzerThen use it in your code:
import { DependencyGraph, GraphAnalyzer, GraphVisualizer } from 'dependency-graph-analyzer';
const graph = new DependencyGraph();
const g = graph.buildsimple({ 'A': ['B'], 'B': ['C'] });
const analyzer = new GraphAnalyzer(g);
const result = analyzer.analyze();
console.log(result.stats); // { totalNodes: 3, totalEdges: 2, hasCycles: false }Option 3: Install from Source
# Clone the repository
git clone https://github.com/yourusername/dependency-graph-analyzer.git
cd dependency-graph-analyzer
# Install dependencies
npm install
# Build the project
npm run build
# Run locally
npm start
# Server will start at http://localhost:8092/graphql🚀 Quick Start
Using the Live GraphQL API
Open in Browser: Visit https://dep-graph-analyzer.shehan.io/graphql
Example Query:
query {
analyze(dependenciesJson: "{\"A\": [\"B\", \"C\"], \"B\": [\"D\"], \"C\": [\"D\"], \"D\": [\"A\"]}") {
stats {
totalNodes
totalEdges
hasCycles
}
cycles {
nodes
severity
}
topological {
valid
order
}
critical {
name
dependents
rank
}
}
}Response:
{
"data": {
"analyze": {
"stats": {
"totalNodes": 4,
"totalEdges": 5,
"hasCycles": true
},
"cycles": [
{
"nodes": ["D", "C", "B", "A"],
"severity": "ERROR"
}
],
"topological": {
"valid": false,
"order": []
},
"critical": [
{
"name": "C",
"dependents": 2,
"rank": 1
}
]
}
}
}Using as a TypeScript/JavaScript Library
import { DependencyGraph, GraphAnalyzer, GraphVisualizer } from 'dependency-graph-analyzer';
// Define your dependencies
const dependencies = {
'Frontend': ['React', 'API Client'],
'React': ['API Client'],
'API Client': ['API Server'],
'Backend': ['Database', 'API Server'],
'API Server': ['Business Logic'],
'Business Logic': ['Database'],
'Database': []
};
// Build the graph
const graph = new DependencyGraph();
const g = graph.buildsimple(dependencies);
// Analyze it
const analyzer = new GraphAnalyzer(g);
const analysis = analyzer.analyze();
// Check for cycles
if (analysis.stats.hasCycles) {
console.log('❌ Circular dependencies found:', analysis.cycles);
} else {
console.log('✅ No cycles! Install order:', analysis.topological.order);
}
// Find critical packages
console.log('Most critical packages:', analysis.critical.slice(0, 3));
// Generate visualization
const visualizer = new GraphVisualizer(g);
const result = await visualizer.visualize('svg', true, analysis.cycles);
console.log('SVG:', result.svg);🌐 API Reference
Live GraphQL Endpoint
Production URL: https://dep-graph-analyzer.shehan.io/graphql
Local Development: http://localhost:8092/graphql (after running npm start)
GraphQL Schema
type Query {
analyze(dependenciesJson: String!): AnalysisResult!
}
type AnalysisResult {
cycles: [Cycle!]!
components: [StronglyConnectedComponent!]!
topological: TopologicalOrder!
critical: [CriticalPackage!]!
stats: Stats!
visualization: Visualization!
}
type Cycle {
nodes: [String!]!
severity: Severity! # ERROR or WARNING
}
type StronglyConnectedComponent {
nodes: [String!]!
size: Int!
}
type TopologicalOrder {
order: [String!]!
valid: Boolean!
}
type CriticalPackage {
name: String!
dependents: Int!
rank: Int!
}
type Stats {
totalNodes: Int!
totalEdges: Int!
hasCycles: Boolean!
}
type Visualization {
dot: String! # GraphViz DOT format
svg: String # SVG image (can be rendered in browser)
}Query Examples
Get only statistics:
query {
analyze(dependenciesJson: "{\"A\": [\"B\"], \"B\": [\"C\"]}") {
stats {
totalNodes
hasCycles
}
}
}Get only cycles:
query {
analyze(dependenciesJson: "{\"express\": [\"body-parser\"], \"body-parser\": [\"express\"]}") {
cycles {
nodes
severity
}
}
}Get visualization only:
query {
analyze(dependenciesJson: "{\"A\": [\"B\"], \"B\": [\"C\"]}") {
visualization {
svg
}
}
}Get everything:
query {
analyze(dependenciesJson: "{\"A\": [\"B\"]}") {
stats { totalNodes totalEdges hasCycles }
cycles { nodes severity }
components { nodes size }
topological { order valid }
critical { name dependents rank }
visualization { svg dot }
}
}📚 Use Cases & Examples
Example 1: Software Package Dependencies
Scenario: Analyze npm package circular dependencies
query {
analyze(dependenciesJson: "{\"express\": [\"body-parser\"], \"body-parser\": [\"express\"], \"morgan\": [\"express\"], \"cors\": []}") {
cycles {
nodes
severity
}
stats {
hasCycles
}
}
}Expected: Detects cycle between express ↔ body-parser
Example 2: Microservices Architecture
Scenario: Visualize service dependencies and find tightly coupled components
query {
analyze(dependenciesJson: "{\"api-gateway\": [\"auth-service\", \"user-service\"], \"auth-service\": [\"database\", \"cache\"], \"user-service\": [\"database\", \"email-service\"], \"email-service\": [\"queue\"], \"database\": [], \"cache\": [], \"queue\": []}") {
stats {
totalNodes
hasCycles
}
topological {
order
}
critical {
name
dependents
}
}
}Expected: Database is most critical (3 dependents), no cycles, valid order
Example 3: Course Prerequisites
Scenario: Plan academic path with prerequisite constraints
query {
analyze(dependenciesJson: "{\"Advanced AI\": [\"Machine Learning\", \"Linear Algebra\"], \"Machine Learning\": [\"Statistics\", \"Python Programming\"], \"Deep Learning\": [\"Machine Learning\", \"Calculus\"], \"Statistics\": [\"Math 101\"], \"Linear Algebra\": [\"Math 101\"], \"Calculus\": [\"Math 101\"], \"Python Programming\": [], \"Math 101\": []}") {
topological {
order
valid
}
critical {
name
dependents
}
}
}Expected: Math 101 and Machine Learning are most critical, clear learning path
Example 4: Build System with Circular Dependency (Error Case)
Scenario: Detect circular build dependencies in monorepo
query {
analyze(dependenciesJson: "{\"app\": [\"lib-a\", \"lib-b\"], \"lib-a\": [\"lib-c\"], \"lib-b\": [\"lib-c\"], \"lib-c\": [\"lib-a\"]}") {
stats {
hasCycles
}
cycles {
nodes
severity
}
components {
nodes
size
}
}
}Expected: Cycle detected: lib-a → lib-c → lib-a
Example 5: Full Stack Architecture Visualization
Scenario: Generate architecture diagram with SVG
query {
analyze(dependenciesJson: "{\"Frontend\": [\"React\", \"API Client\"], \"React\": [\"API Client\"], \"API Client\": [\"API Server\"], \"Backend\": [\"Database\", \"API Server\"], \"API Server\": [\"Business Logic\"], \"Business Logic\": [\"Database\"], \"Database\": []}") {
stats {
totalNodes
totalEdges
hasCycles
}
topological {
order
}
visualization {
svg
dot
}
}
}Expected: Clean architecture, no cycles, SVG showing layered design
🧪 Testing
Test in Browser (GraphQL Playground)
- Visit: https://dep-graph-analyzer.shehan.io/graphql
- Paste any query from examples above
- Click "Run"
- See results instantly!
Test with curl
# Simple test
curl -X POST https://dep-graph-analyzer.shehan.io/graphql \
-H "Content-Type: application/json" \
-d '{"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"], \\\"B\\\": [\\\"C\\\"]}\") { stats { totalNodes hasCycles } } }"}'
# With cycles
curl -X POST https://dep-graph-analyzer.shehan.io/graphql \
-H "Content-Type: application/json" \
-d '{"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"], \\\"B\\\": [\\\"A\\\"]}\") { cycles { nodes severity } } }"}'Test with Postman
- Method: POST
- URL:
https://dep-graph-analyzer.shehan.io/graphql - Headers:
Content-Type: application/json
- Body (raw JSON):
{
"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"], \\\"B\\\": [\\\"C\\\"]}\") { stats { totalNodes hasCycles } topological { order } } }"
}Test with JavaScript/Node.js
const query = `
query {
analyze(dependenciesJson: "{\\"A\\": [\\"B\\"], \\"B\\": [\\"C\\"]}") {
stats { totalNodes hasCycles }
topological { order }
}
}
`;
fetch('https://dep-graph-analyzer.shehan.io/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
})
.then(res => res.json())
.then(data => console.log(data));Test with Python
import requests
query = """
query {
analyze(dependenciesJson: "{\\"A\\": [\\"B\\"], \\"B\\": [\\"C\\"]}") {
stats { totalNodes hasCycles }
topological { order }
}
}
"""
response = requests.post(
'https://dep-graph-analyzer.shehan.io/graphql',
json={'query': query},
headers={'Content-Type': 'application/json'}
)
print(response.json())Run Local Tests
If you've cloned the repository:
# Run test suite
npm test
# Start local server
npm run dev
# Test locally
curl -X POST http://localhost:8092/graphql \
-H "Content-Type: application/json" \
-d '{"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"]}\") { stats { totalNodes } } }"}'📖 Real-World Test Scenarios
See examples/REAL_WORLD_TESTS.md for 10+ real-world test cases including:
- ✅ Python Django dependencies
- ✅ Node.js circular dependencies
- ✅ Microservices architecture
- ✅ Course prerequisites
- ✅ Build system cycles
- ✅ Team skill dependencies
- ✅ Monorepo analysis
- ✅ Diamond dependency problem
🔧 Local Development
Setup
# Clone repository
git clone https://github.com/yourusername/dependency-graph-analyzer.git
cd dependency-graph-analyzer
# Install dependencies
npm install
# Build TypeScript
npm run build
# Start development server
npm run devProject Structure
dependency-graph-analyzer/
├── src/
│ ├── types.ts # TypeScript interfaces
│ ├── graph.ts # Graph building (buildsimple, build)
│ ├── analyzer.ts # Tarjan's, cycles, topsort, getcritical
│ ├── visualizer.ts # GraphViz integration
│ ├── schema.ts # GraphQL schema
│ ├── resolvers.ts # GraphQL resolvers
│ ├── server.ts # Apollo Server
│ └── index.ts # Library exports
├── examples/
│ ├── test.ts # Example usage
│ ├── viewer.html # SVG viewer
│ └── REAL_WORLD_TESTS.md # Test scenarios
├── dist/ # Compiled JavaScript (gitignored)
├── package.json
├── tsconfig.json
├── Procfile # Heroku deployment
└── README.mdAvailable Scripts
npm run build # Compile TypeScript to JavaScript
npm start # Run production server (dist/server.js)
npm run dev # Run development server with ts-node
npm test # Run test suite🤝 Contributing
Contributions are welcome! Here's how:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙋 Support
- Issues: GitHub Issues
- Live API: https://dep-graph-analyzer.shehan.io/graphql
- Author: @yourusername
- Email: [email protected]
🌟 Acknowledgments
- Built with graphlib for graph operations
- Visualization powered by GraphViz via @viz-js/viz
- GraphQL API with Apollo Server
- Deployed on Heroku
- Inspired by the need for universal dependency analysis across all domains
🚀 Key Features Recap
✅ Tarjan's Algorithm - O(V+E) complexity for finding SCCs
✅ Cycle Detection - ERROR/WARNING severity levels
✅ Topological Sort - Valid build/install ordering
✅ Critical Analysis - Identify most-depended-on packages
✅ GraphViz Visualization - SVG/DOT format with cycle highlighting
✅ GraphQL API - Query exactly what you need
✅ TypeScript - Full type safety
✅ Live & Production-Ready - https://dep-graph-analyzer.shehan.io/graphql
Made by Shehan Horadagoda
⭐ Star this repo if you find it useful!
