Skip to content
Arxo Arxo

Graph Types

Arxo builds and analyzes multiple graph representations of your codebase. Each graph captures different architectural relationships.

The Import Graph represents module-level dependencies extracted from import/require statements.

Nodes: Files, modules, or packages (depending on grouping) Edges: Import/dependency relationships

src/components/Button.tsx
import { theme } from '../styles/theme';
import { logger } from '../utils/logger';
// src/pages/Home.tsx
import { Button } from '../components/Button';

Import Graph:

pages/Home.tsx → components/Button.tsx
components/Button.tsx → styles/theme.tsx
components/Button.tsx → utils/logger.tsx

Control granularity with group_by and group_depth:

File-level (default):

import_graph:
group_by: file

Folder-level:

import_graph:
group_by: folder
group_depth: 1 # Group by immediate parent folder

Package-level:

import_graph:
group_by: folder
group_depth: 2 # Group by top-level packages
  • Detect circular dependencies (SCC metric)
  • Measure propagation cost
  • Identify architectural layers
  • Validate import rules

The Call Graph represents function and method invocations.

Nodes: Functions, methods, classes Edges: Function calls, method invocations

utils/logger.ts
export function log(message: string) {
console.log(message);
}
// services/api.ts
import { log } from '../utils/logger';
export async function fetchData(url: string) {
log(`Fetching ${url}`);
return fetch(url);
}
// components/DataLoader.tsx
import { fetchData } from '../services/api';
export function DataLoader() {
const data = fetchData('/api/data');
// ...
}

Call Graph:

DataLoader() → fetchData()
fetchData() → log()
fetchData() → fetch()

Arxo tracks calls across language boundaries:

TypeScript → Python (via REST API):

frontend/api.ts
fetch('/api/analyze')
// backend/main.py
@app.route('/api/analyze')
def analyze():
return run_analysis()
  • Analyze runtime dependencies
  • Find unused functions
  • Detect code smells (God functions)
  • Impact analysis for changes

The Entity Graph represents high-level component relationships.

Nodes: Files, modules, components Edges: Various relationships (imports, calls, shared types)

In a React application:

Feature/Auth → Component/LoginForm
Feature/Auth → Service/AuthAPI
Service/AuthAPI → Util/Http
Component/LoginForm → Util/Validation
  • High-level architecture visualization
  • Component boundaries
  • Feature dependencies
  • Architectural diagrams

Each graph enables different metrics:

MetricWhat It Measures
SCCCircular dependencies
Propagation CostChange impact
ModularityCommunity structure
HierarchyLayer violations
MetricWhat It Measures
Call DepthNesting complexity
Unused FunctionsDead code
Effect ViolationsSide effect boundaries
Critical PathMost-called functions
MetricWhat It Measures
CentralityCritical components
Core-PeripheryArchitectural zones
CouplingComponent dependencies

Export graphs for visualization:

Terminal window
# Export import graph as GraphML
arxo analyze --format json --output report.json
# Extract graph from report
jq '.graphs.import_graph' report.json > import_graph.json

Use these tools to visualize exported graphs:

  • Graphviz - DOT format rendering
  • Gephi - Network analysis and visualization
  • Cytoscape - Biological network visualization
  • D3.js - Custom web visualizations
  • Neo4j - Graph database queries

Convert Arxo output to DOT format:

import json
with open('report.json') as f:
report = json.load(f)
import_graph = report['graphs']['import_graph']
print('digraph G {')
for node in import_graph['nodes']:
print(f' "{node}" [label="{node}"];')
for edge in import_graph['edges']:
print(f' "{edge["source"]}" -> "{edge["target"]}";')
print('}')

Render with Graphviz:

Terminal window
python to_dot.py | dot -Tpng -o graph.png

Filter out noise:

import_graph:
exclude:
- "**/node_modules/**"
- "**/test/**"
- "**/*.test.ts"
- "**/dist/**"
import_graph:
languages:
- typescript
- python
exclude:
- "**/*.spec.ts" # TypeScript tests
- "**/test_*.py" # Python tests

Limit graph size for performance:

import_graph:
max_nodes: 10000
max_edges: 50000

Graphs are cached between runs:

Terminal window
# Cache location (default)
~/.cache/arxo/graphs/<project-hash>/
# Disable caching
arxo analyze --no-analysis-cache
# Clear cache
arxo cache clear

When files change, Arxo:

  1. Detects changed files (via git or filesystem)
  2. Invalidates affected graph nodes
  3. Re-parses only changed files
  4. Updates graph edges
  5. Recomputes affected metrics

Future feature: Query graphs directly

Terminal window
# Find all paths from A to B
arxo graph query --from "src/A.ts" --to "src/B.ts"
# Find modules with most dependencies
arxo graph query --top-dependencies 10