Skip to content

Explore the Code Graph

Unfault builds a graph of your codebase: which files import which, which functions call which, which libraries are used where. The unfault graph command lets you query this graph to understand your code’s structure and plan changes safely.

Before changing code, you want to know what might break. The graph answers questions like:

  • “If I refactor auth.py, what else needs to change?”
  • “Which files use the requests library?”
  • “What are the most interconnected files in this codebase?”

These questions are hard to answer by grepping. The graph understands imports, function calls, and transitive dependencies.

Before refactoring a file, see what depends on it:

Terminal window
unfault graph impact src/api/auth.py

Output:

🔍 Impact Analysis: src/api/auth.py
→ This file is used by 15 file(s)
10 direct, 5 through transitive dependencies
Direct Dependencies
Files that import this directly — changes here affect them first
────────────────────────────────────────────────────────────
• src/api/routes/users.py [Python]
• src/api/routes/admin.py [Python]
• src/api/middleware/auth.py [Python]
• src/services/payments.py [Python]
...
Transitive Dependencies
Files that depend on this indirectly — ripple effects
────────────────────────────────────────────────────────────
→→ src/api/routes/orders.py [Python] (2 hops)
→→ src/api/routes/checkout.py [Python] (2 hops)
...
💡 This is a hub file. Consider extra care when modifying.

The direct dependents are files that import from auth.py. Transitive dependencies show files that depend on those dependents. Changes ripple outward.

By default, transitive analysis goes 5 levels deep. For large codebases, you might want to limit this:

Terminal window
unfault graph impact --max-depth 2 src/core/models.py

Or expand it for a fuller picture:

Terminal window
unfault graph impact --max-depth 10 src/core/models.py

Sometimes you’re changing a single function, not a whole file. The graph can be more precise:

Terminal window
unfault graph function-impact src/api/auth.py:validate_token

This shows only the files and functions that call validate_token, not everything that imports auth.py.

Auditing a dependency? See where it’s used:

Terminal window
unfault graph library requests

Output:

📚 Library Usage: requests
→ 'requests' is used in 7 file(s)
Usage Locations
These files import this library directly
────────────────────────────────────────────────────────────
• src/clients/payment.py [Python]
• src/clients/shipping.py [Python]
• src/scripts/migrate.py [Python]
• src/services/notifications.py [Python]
...
💡 This library is used widely. Consider its stability and versioning.

This is useful when:

  • Migrating from one library to another (requests to httpx)
  • Auditing security vulnerabilities in a dependency
  • Understanding how broadly a library is used

The inverse question: what does this file depend on?

Terminal window
unfault graph deps src/api/routes/payments.py

Output:

Dependencies for src/api/routes/payments.py
Internal imports (5):
← src/api/auth.py
← src/core/models.py
← src/services/stripe.py
← src/services/notifications.py
← src/utils/logging.py
External libraries (4):
← fastapi
← sqlalchemy
← pydantic
← structlog

This helps when:

  • Understanding a file before modifying it
  • Checking if a file has too many dependencies
  • Auditing what a module actually needs

Every codebase has hub files: highly connected, imported by many others. These are your most critical files. Changes to them have wide impact.

Terminal window
unfault graph critical

Output:

🎯 Hub Files Analysis
Files with the most connections — changes here have the widest impact
→ Analyzing 185 files, showing top 10
# File In Out Libs Score
─────────────────────────────────────────────────────────────────
1 src/__init__.py 56 0 0 112
2 src/database.py 47 1 11 106
3 src/dependencies/database.py 28 1 2 59
4 src/config.py 27 0 4 58
5 src/schemas.py 19 0 3 41
...
💡 '__init__.py' is a major hub. Consider extra review for changes.
Legend: In: dependents | Out: dependencies | Libs: external packages
Higher score = more central to the codebase

These are files to handle with care. Changes here ripple widely.

You can sort by different metrics:

Terminal window
# Files most imported by others (default)
unfault graph critical --sort-by in-degree
# Files that import the most (sprawling dependencies)
unfault graph critical --sort-by out-degree
# Total connectivity (hubs)
unfault graph critical --sort-by total-degree
# Most external library usage
unfault graph critical --sort-by library-usage
Terminal window
# Top 20 critical files
unfault graph critical --limit 20
# Just the top 3
unfault graph critical --limit 3

For a high-level view of your codebase structure:

Terminal window
unfault graph stats

Output:

🗺️ Code Graph Overview
A map of your codebase structure and connections
→ 723 code units across 185 files
Structure
─────────────────────────────────────────────
📄 Files 185
⚙️ Functions 723
📦 Classes 0
📚 External Libraries 69
─────────────────────────────────────────────
Total nodes 978
Connections
─────────────────────────────────────────────
🔗 File imports 409
📍 File→function/class 731
📚 Library usage 656
➡️ Function calls 628
─────────────────────────────────────────────
Total edges 2680

All graph commands support --json for programmatic use:

Terminal window
unfault graph impact --json src/api/auth.py
unfault graph critical --json --limit 5

This is useful for:

  • CI/CD checks (“fail if this file has more than N dependents”)
  • Custom tooling
  • Integration with other systems
  1. Check what depends on the file you’re changing:

    Terminal window
    unfault graph impact src/core/models.py
  2. If the impact is large, consider whether to:

    • Break the change into smaller pieces
    • Add deprecation warnings first
    • Update dependents in the same PR
  3. After making changes, run a review to catch issues:

    Terminal window
    unfault review
  1. Find all usage of the library:

    Terminal window
    unfault graph library requests
  2. Check each file for patterns (timeouts, retries):

    Terminal window
    unfault review --dimension stability
  3. If migrating, you now have a complete list of files to update.

  1. Get the overall shape:

    Terminal window
    unfault graph stats
  2. Find the critical files (these are the “load-bearing walls”):

    Terminal window
    unfault graph critical --limit 10
  3. Pick a critical file and see what depends on it:

    Terminal window
    unfault graph impact src/core/models.py

CLI Reference

Full option reference for graph commands. Read more

Ask Questions

Query your codebase in natural language. Read more