Universal dependency graph analysis with cycle detection, Tarjan's algorithm, and GraphViz visualization
Live Demo β’ Installation β’ Quick Start β’ API Reference β’ Examples
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?
- 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
| 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 |
Simply send GraphQL queries to:
https://dep-graph-analyzer.shehan.io/graphql
Quick 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 } } }"}'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 }# 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/graphqlOpen 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
}
]
}
}
}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);Production URL: https://dep-graph-analyzer.shehan.io/graphql
Local Development: http://localhost:8092/graphql (after running npm start)
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)
}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 }
}
}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
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
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
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
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
- Visit: https://dep-graph-analyzer.shehan.io/graphql
- Paste any query from examples above
- Click "Run"
- See results instantly!
# 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 } } }"}'- 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 } } }"
}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));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())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 } } }"}'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
# 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 devdependency-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.md
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 suiteContributions 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
This project is licensed under the MIT License - see the LICENSE file for details.
- Issues: GitHub Issues
- Live API: https://dep-graph-analyzer.shehan.io/graphql
- Author: @yourusername
- Email: shehan87h@gmail.com
- 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
β
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