Code Explorer is a powerful Python code analyzer and dependency analysis tool with persistent graph storage in SQLite (FTS5/BM25). Designed for developers who need to understand complex codebases, track dependencies, and perform impact analysis efficiently.
Code Explorer is the best Python code analyzer for understanding large codebases. It builds a persistent dependency graph by analyzing Python files to track functions, classes, variables, and their relationships (calls, imports, inheritance). This free Python code analyzer enables sophisticated impact analysis and code navigation through graph-based queries.
Key Capabilities:
- 🔍 Dependency Tracking - Map all function calls, imports, and class relationships
- 📊 Impact Analysis - Identify code affected by changes before refactoring
- 🗺️ Code Visualization - Generate Mermaid diagrams of dependencies
- ⚡ Fast Queries - Sub-second graph database queries
- 💾 Incremental Updates - Only re-analyze changed files (10-100x faster)
- 🎯 AST-Based - Accurate static code analysis without execution
- 🔎 Code Search (experimental) - BM25/fuzzy/semantic search with an LLM-ready context bundle for the top hit (
code-explorer search "...") - 📏 Measured, not asserted - every retrieval claim below is reproducible from committed run files: see benchmarks, the harness, and the generated reports
Code Explorer excels at analyzing complex Python codebases where understanding dependencies is critical:
✅ Enterprise-Grade Performance - Analyze 10,000+ file codebases in minutes ✅ Graph Storage, No Server - SQLite with FTS5/BM25 by default: no daemon, no native dependency, and faster to index than the alternatives measured below ✅ Comprehensive Analysis - Functions, classes, imports, decorators, variables, exceptions ✅ Persistent Storage - Results saved to disk for instant reuse ✅ Command-Line First - Perfect for CI/CD integration and automation
| Feature | Code Explorer | pylint/flake8 | IDE Navigation |
|---|---|---|---|
| Relationship Analysis | ✅ Graph-based | ❌ Syntax only | |
| Impact Analysis | ✅ Multi-level | ❌ None | |
| Visualization | ✅ Diagrams | ❌ Text only | ❌ None |
| Persistent Storage | ✅ Database | ❌ None | ❌ None |
| CI/CD Integration | ✅ CLI-first | ❌ Not designed |
The claims above are the ones any tool makes about itself. The ones below are
measured - against ground truth mined from a repository's own git history (the
commit subject is the query, the files it touched are the answers), scored with
ranx with paired significance testing.
Two corpora, 350 queries, versus zvec-grep:
| index build | query | recall@10 | |
|---|---|---|---|
| django - Code Explorer | 0.29 min | 471 ms | 0.798 |
| django - zg | 0.40 min | 1,165 ms | 0.646 |
| home-assistant (18,631 files) - Code Explorer | 1.51 min | 1,083 ms | 0.807 |
| home-assistant - zg | 2.50 min | 5,838 ms | 0.552 |
Faster to index, faster to query, and significantly better recall - in the default SQLite/BM25 mode, with no embeddings, no server and no native dependencies.
The caveat that makes those numbers honest. A query set mined from commits mixes two opposite questions, because a commit that changes behaviour changes its tests. The table above scores "where is this implemented?". On "what covers this?" zg wins by as large a margin (0.651 vs 0.444 on django; 0.522 vs 0.152 on home-assistant) - a direct consequence of Code Explorer demoting test files so an implementation outranks its own tests. Averaged together the two cancel out and the tools look tied, which is what the aggregate tables in the reports show. Neither tool dominates; they answer different questions.
The reports are generated, never hand-edited, and regenerate on every run:
| File | What it holds |
|---|---|
bench/results/reports/django/summary.md |
Cross-tool tables (code / test / aggregate), what actually ran, complementarity, cost |
bench/results/reports/home-assistant/summary.md |
The same, on a 7x larger corpus |
docs/explanation/gap-analysis-vs-zvec.md |
Where the gap was, what closed it, and what did not |
docs/explanation/benchmarking.md |
Why the harness is built this way |
docs/explanation/architecture-index-and-search.md |
The two pipelines, with the cost of each stage |
Reproducing them:
cd bench
uv venv --python 3.12 && uv pip install -e .
uv run python -m bench.runner --corpus django --index -k 10 # run every tool
uv run python -m bench.report --corpus django # regenerate reportsSame harness, same two corpora, against
ripwire - a tree-sitter call-graph
ranker over 22+ languages, queried through its own recommended --for=TASK
lens:
| code recall@10 | test recall@10 | query | tokens | |
|---|---|---|---|---|
| django - Code Explorer (hybrid) | 0.847 | 0.497 | 727 ms | 2,201 |
| django - ripwire | 0.862 | 0.094 | 578 ms | 3,294 |
| django - zg | 0.646 | 0.651 | 1,165 ms | 344 |
| home-assistant - Code Explorer (body) | 0.807 | 0.152 | 1,083 ms | 1,426 |
| home-assistant - ripwire | 0.821 | 0.000 | 3,941 ms | 3,427 |
| home-assistant - zg | 0.552 | 0.522 | 5,838 ms | 387 |
On "where is this implemented?" ripwire edges out every configuration we measured, on both corpora - the best code-only recall@10 in either table, and it gets there indexing every language in the repo, not just Python.
The same caveat as above, sharper. On "what covers this?" ripwire
collapses to 0.094 on django and 0.000 on home-assistant - it essentially
never returns a test file, more aggressively than Code Explorer's own test
demotion. Averaged together (the delivered metric in the reports) that
puts ripwire mid-pack on both corpora, behind Code Explorer's hybrid/body
configurations and behind zg - not because its retrieval is weaker, but
because the average is exactly two questions and it only answers one of
them. It also has no persistent index: every query cold-parses the corpus
behind a per-root cache in the OS tmpdir, which is why its query cost rises
with corpus size (578 ms on django, 3.9 s on the 7x-larger home-assistant)
where Code Explorer's and zg's stay flat against a prebuilt index.
Pick the tool for the question you're actually asking: ripwire for "where's the implementation", zg or Code Explorer's hybrid configuration when tests matter too, plain Code Explorer when query cost is the constraint. Full tables, complementarity (how much of what ripwire finds no other tool returns at any rank), and per-query detail are in the same generated reports linked above.
Capability map. The numbers above are all retrieval - the one thing all three tools do. That is the whole job for two of them and a single verb out of many for the third:
| Capability | Code Explorer | zg (zvec-grep) | ripwire |
|---|---|---|---|
| Language coverage | Python only | Every file type | 22+ languages (tree-sitter) |
| Ranking method | BM25/FTS5, optionally fused with vector similarity (reciprocal rank fusion) | Hybrid FTS + vector by default | Personalized PageRank over a parsed call graph, BM25-routed by query shape |
| Vector/semantic search | Optional (--semantic) |
Yes, default-on | No |
| Unit of retrieval | Whole symbols | Text chunks, no symbol identity | Individual symbols, graph-ranked |
| Context expansion beyond seed hits | Yes - graph-hop expansion into a bundle | No | No (--json; its non-JSON dialect can inline top bodies, which is more detail, not more files) |
| Persistent index | Yes, built once | Yes, built once | No - cold-parses per invocation behind a tmpdir cache |
| Call-graph structural queries (callers, blast radius) | Yes - its original purpose | No | Yes (--callers, --uses, --impact, a small graph-query DSL) |
| Code quality / architecture analysis | No | No | Yes - hotspots, complexity, clone detection, dependency-cycle/layering rules with CI gates |
| Test-impact analysis | No | No | Yes (--test-gate) |
| Stack-trace triage | No | No | Yes (--from-trace) |
| Agent/MCP integration | No | No | Yes - ripwire wrap <agent>, MCP server mode, packaged agent skills |
| Deployment | Python package | Native binary + local embedding runtime | Single static binary, zero runtime deps |
| What the table above measures | Its whole job | Its whole job | One verb (--for) among many |
--backend still accepts kuzu and lattice, and both are obsolete. They
are kept so existing indexes remain readable, and neither is maintained or
measured:
| backend | status | why |
|---|---|---|
| sqlite | the only supported one | FTS5/BM25, no server, no native dependency, and the fastest to index of the three |
lattice |
obsolete | two verified LatticeDB 0.15.0 defects, one of which returns [] for any multi-term query where a term appears in more than one document - that breaks the primary use case |
kuzu |
obsolete | predates the search index; analyze builds a second, disconnected graph with a naive call resolver (~5.5x spurious fan-out) that none of the retrieval work above applies to |
Every benchmark in this README is SQLite. Do not read a number here as saying anything about the other two.
The harness lives in bench/ and is deliberately external: it never
imports code_explorer, drives every tool as a subprocess, and compares each at
its best configuration rather than at its default. Corpora are declared in
bench/corpora.toml, tool configurations in
bench/adapters.toml - adding a third tool is one adapter
file. Raw run files are committed under
bench/results/runs/ so any result can be re-scored later
under a metric nobody had thought of yet, and
bench/analysis/ holds the one-off scripts behind
every number quoted in the docs.
It is free to report that Code Explorer loses - and it does, on the test-retrieval question above, and on several configurations we measured and then rejected.
The best free Python code analyzer is just a pip install away:
# Install from source
pip install -e .
# Or install from PyPI (when published)
pip install code-explorerRequirements:
- Python 3.8 or higher
- Dependencies: click, rich, astroid, kuzu, pandas
Step 1: Analyze Your Codebase
# Analyze current directory
code-explorer analyze .
# Analyze specific directory
code-explorer analyze ./src
# Include normally excluded directories
code-explorer analyze . --include .venvExample Output:
Analyzing codebase at: /path/to/project
Database location: .code-explorer/graph.db
Excluding: __pycache__, .pytest_cache, dist, build, .git
✓ 234 files analyzed
✓ 1,523 functions inserted
✓ 287 classes inserted
✓ 892 variables inserted
✓ 2,145 import relationships
✓ 8,734 function call edges
Total analysis time: 12.3s
Step 2: View Codebase Statistics
code-explorer statsOutput shows:
- Total files, classes, functions, variables
- Most-called functions (complexity hotspots)
- Import statistics
- Decorator usage
- Exception handling patterns
Step 3: Find Impact of Changes
Before refactoring any function, use this dependency analysis guide:
# Find who calls this function (upstream dependencies)
code-explorer impact src/module.py:my_function
# Find what this function calls (downstream dependencies)
code-explorer impact src/module.py:my_function --downstream
# Limit expansion depth for a focused, cheaper bundle
code-explorer impact src/module.py:my_function --depth 2Step 4: Visualize Dependencies
Generate beautiful dependency graphs:
# Create Mermaid diagram for a module
code-explorer visualize src/module.py --output graph.md
# Focus on specific function with depth limit
code-explorer visualize src/utils.py --function calculate --max-depth 2
# View in GitHub, VS Code, or any Mermaid-compatible viewerSecond and subsequent runs are dramatically faster:
# Only analyzes changed files (10-100x faster)
code-explorer analyze ./src
# Force complete re-analysis when needed
code-explorer analyze ./src --refreshHow it works:
- File content hashes are stored in the database
- Unchanged files are automatically skipped
- Only modified files are re-analyzed
- Perfect for development workflow and CI/CD
For projects with 10,000+ files or including virtual environments:
# Include a directory normally excluded by default
code-explorer analyze . --include .venv
# Increase parallel workers for faster processing
code-explorer analyze . --workers 16Manage database size by controlling source code storage:
# Don't store full source code (default, smaller database)
code-explorer analyze ./src
# Store each function/class's full source_code as a graph property
code-explorer analyze ./src --include-sourceStart fresh analysis from scratch:
# Delete the database directory
rm -rf .code-explorer/
# Or use refresh flag
code-explorer analyze ./src --refreshUse custom database paths for multiple projects or specific locations:
# Specify custom database path
code-explorer analyze ./src --db-path /path/to/custom/db
# All subsequent commands must use the same path
code-explorer stats --db-path /path/to/custom/db
# (impact reads the `search` index instead, under <path>/.code-explorer/)Prevent accidental modifications:
# The KuzuDB Explorer runs in read-only mode by default
docker compose up -d
# Open http://localhost:8000
# Run Cypher queries safely without risking data corruptionIdentify code that needs refactoring:
# Show top 20 most-called functions
code-explorer stats --top 20
# These are complexity hotspots - refactoring candidatesAdd dependency analysis to your continuous integration:
#!/bin/bash
# .github/workflows/analyze.sh
# Analyze codebase
code-explorer analyze . --refresh
# Generate complexity report
code-explorer stats --top 50 > complexity-report.txt
# Fail build if critical functions are too complex
# (add custom logic based on your thresholds)Analyzes Python files and builds the dependency graph.
Options:
--exclude PATTERN- Exclude files/directories (can specify multiple times)--include PATTERN- Override default exclusions (e.g.,--include .venv)-w, --workers N- Number of worker threads (default: auto-detect CPU count)--db-path PATH- Custom database location (default:.code-explorer/graph.db)--refresh- Force complete re-analysis (clears existing database)--include-source- Store each function/class's full source code as a graph property (opt-in, off by default)
Examples:
# Basic analysis
code-explorer analyze ./src
# Complex project with multiple exclusions
code-explorer analyze . --exclude tests --exclude docs --workers 8
# Analyze everything including virtual environment
code-explorer analyze . --include .venv --include venv
# Keep full source code in the graph
code-explorer analyze . --include-sourceShows comprehensive graph statistics.
Options:
--top N- Show top N most-connected functions (default: 10)--db-path PATH- Custom database location
Examples:
# Basic statistics
code-explorer stats
# Show top 25 most-called functions
code-explorer stats --top 25Expands one named function into a context bundle: what calls it, what it
calls, with source attached. Same engine as search -- search finds the
seed from a query, impact is handed the seed.
Reads the index search builds (.code-explorer/graph.lattice), building
or updating it as needed. stats and visualize still read analyze's
separate Kuzu graph.
Options:
--downstream/--upstream- one direction only (default: both)--depth N- hops to collect before ranking (default: 3)--budget N- token budget for the bundle (default: 12,000); nodes past it degrade to signatures rather than being cut mid-function--names-only- list the ranked neighbourhood without reading source--backend {lattice,sqlite}- which search index to use--reindex- force a fresh index
Examples:
# What calls this, and what it calls
code-explorer impact services/auth.py:validate_user
# Only what this function calls
code-explorer impact utils/helpers.py:process_data --downstream
# Tighter, cheaper bundle
code-explorer impact main.py:run --depth 2 --budget 4000
# Just the names -- no source reads at all
code-explorer impact main.py:run --names-onlyGenerates Mermaid dependency diagrams.
Options:
--function NAME- Highlight specific function--output PATH- Output file path (default: graph.md)--max-depth N- Limit diagram depth (default: 3)--db-path PATH- Custom database location
Examples:
# Visualize entire module
code-explorer visualize services/auth.py --output auth_graph.md
# Focus on specific function with depth control
code-explorer visualize utils.py --function calculate --max-depth 2BM25/fuzzy/semantic code search with an LLM-ready context bundle (top hit +
its direct callers/callees, source attached). Uses the SQLite search index,
not the legacy graph database the older commands use - see
docs/reference/cli-commands.md
for the full reference, including the --semantic mode's local-Ollama
requirement.
Options:
--limit N- Maximum results (default: 5)--fuzzy- Typo-tolerant search instead of BM25--semantic- Vector search instead of BM25 (needs local Ollama)--no-context- Only show the results table--reindex- Force a fresh index
Examples:
# Keyword search with a ready-to-use context bundle for the top hit
code-explorer search "resolve call" src
# Typo-tolerant
code-explorer search "refesh_token" --fuzzy
# Conceptual search (ollama pull nomic-embed-text first)
code-explorer search "walking a syntax tree recursively" src --semanticNode Types:
-
File - Python source files
path(STRING) - Relative file pathcontent_hash(STRING) - SHA-256 hash for change detectionlast_modified(TIMESTAMP) - Last modification time
-
Function - Functions and methods
id(STRING) - Hash-based ID (fn_*)name(STRING) - Function namefile(STRING) - Relative file pathstart_line,end_line(INT64) - Location in sourceis_public(BOOLEAN) - Public/private visibilitysource_code(STRING, optional) - Function source code
-
Class - Class definitions
id(STRING) - Hash-based ID (cls_*)name(STRING) - Class namefile(STRING) - Relative file pathstart_line,end_line(INT64) - Location in sourcebases(STRING) - JSON array of base classesis_public(BOOLEAN) - Public/private visibilitysource_code(STRING, optional) - Class source code
-
Variable - Variable definitions
id(STRING) - Hash-based ID (var_*)name(STRING) - Variable namefile(STRING) - Relative file pathdefinition_line(INT64) - Where definedscope(STRING) - module, class, or function
-
Import - Import statements
id(STRING) - Hash-based ID (imp_*)imported_name(STRING) - What was importedimport_type(STRING) - import or from-importalias(STRING) - Import alias if anyline_number(INT64) - Location in source
-
Decorator - Decorator applications
id(STRING) - Hash-based ID (dec_*)name(STRING) - Decorator namefile(STRING) - Relative file pathline_number(INT64) - Location in sourcearguments(JSON) - Decorator arguments
Edge Types:
CONTAINS_FUNCTION- File contains FunctionCONTAINS_CLASS- File contains ClassCONTAINS_VARIABLE- File contains VariableCALLS- Function calls FunctionMETHOD_OF- Function is method of ClassINHERITS- Class inherits from ClassHAS_IMPORT- File has ImportUSES- Function uses VariableHAS_ATTRIBUTE- Class has AttributeDECORATED_BY- Function/Class decorated by Decorator
CODE_EXPLORER_DEBUG
Enable detailed debug logging:
# Show verbose logging for troubleshooting
CODE_EXPLORER_DEBUG=1 code-explorer analyze .Traditional Python code analyzer tools re-parse the entire codebase on every run. Code Explorer persists its graph in SQLite, providing:
Incremental Updates - Only re-analyze changed files (10-100x faster for large codebases) Complex Queries - Cypher-like graph queries for sophisticated dependency analysis Interactive Exploration - Web UI for visual graph navigation ACID Transactions - Reliable, consistent persistence
The dependency analysis tool intelligently tracks changes:
- Each file has a SHA-256 content hash stored in the database
- On re-analysis, current file hash is compared with stored hash
- Unchanged files are skipped entirely (zero parsing overhead)
- Changed files have their old nodes/edges deleted and are re-analyzed
- New files are added to the graph seamlessly
This makes the second and subsequent runs dramatically faster, perfect for development workflow.
Code Explorer uses both for comprehensive Python code analysis:
ast (Python stdlib)
- Fast parsing and structure extraction
- Functions, classes, imports, calls
- Reliable and stable
astroid (third-party)
- Semantic analysis and name resolution
- Type inference capabilities
- Better cross-file understanding
This combination provides accurate dependency tracking without requiring code execution.
SQLite (embedded, no server) provides:
Cypher Query Language - Powerful graph traversal for complex analysis ACID Transactions - Reliable data persistence Embedded Architecture - No separate server needed High Performance - Optimized for relationship queries Perfect Fit - Code dependencies are naturally a graph structure
Code Explorer analyzes static code structure. Be aware of limitations:
❌ Dynamic imports - importlib or __import__() not tracked
❌ Dynamic calls - getattr() or eval() not resolved
❌ Type inference - Limited to static analysis capabilities
❌ Monkey patching - Runtime modifications not detected
❌ Generated code - Metaprogramming not fully analyzed
For runtime behavior analysis, complement Code Explorer with profiling tools.
1. Run analysis regularly - Integrate into your development workflow 2. Use exclusions wisely - Skip test files and vendor code 3. Check impact before refactoring - Always run impact analysis first 4. Visualize complex areas - Use diagrams for complicated dependencies 5. Monitor statistics - Track code complexity over time 6. Leverage incremental updates - Fast re-analysis in development 7. Integrate with CI/CD - Automated dependency tracking
# Step 1: Find all usages before making changes
code-explorer impact old_module.py:legacy_function --depth 3
# Step 2: Visualize the impact scope
code-explorer visualize old_module.py --function legacy_function
# Step 3: Make changes confidently knowing the full impact
# Step 4: Re-analyze to verify changes
code-explorer analyze . --refresh# New team member can quickly understand codebase structure
code-explorer stats
code-explorer visualize main.py --function main --max-depth 5
# Explore specific areas of interest
code-explorer impact services/core.py:main_handler# Find all functions that touch this problematic code
code-explorer impact utils.py:buggy_function --downstream# In your CI pipeline
code-explorer analyze . --refresh
code-explorer stats --top 100 > complexity-report.txt
# Fail build if complexity threshold exceeded
# Track dependency metrics over timeFor enterprise-scale projects:
# Maximum parallelization
code-explorer analyze . --workers 32
# Analyze incrementally by directory
code-explorer analyze ./src --db-path ./analysis/db
code-explorer analyze ./lib --db-path ./analysis/db
code-explorer analyze ./tests --db-path ./analysis/dbControl memory usage for large analyses:
# Source code is not stored by default (smaller database); only opt in
# with --include-source if you need it
code-explorer analyze .
# Process in stages
code-explorer analyze ./src # First pass
code-explorer analyze ./lib # Second passUsing the web UI for advanced queries:
// Find most complex functions (high fan-in)
MATCH (caller:Function)-[:CALLS]->(callee:Function)
RETURN callee.name, COUNT(caller) as call_count
ORDER BY call_count DESC
LIMIT 20;
// Find circular dependencies
MATCH path = (f:Function)-[:CALLS*]->(f)
RETURN path;
// Find orphaned functions (never called)
MATCH (f:Function)
WHERE NOT (:Function)-[:CALLS]->(f)
RETURN f.name, f.file;- Python 3.8 or higher
- Dependencies: click, rich, astroid, kuzu, pandas
- Docker (optional, for the legacy KuzuDB Explorer web UI)
- 4GB+ RAM recommended for large codebases
- Disk space: ~100MB per 1000 files analyzed (with source code)
Contributions welcome! This free Python code analyzer benefits from community input:
- Report Bugs - Open GitHub issues with details
- Suggest Features - Share ideas for improvements
- Submit Pull Requests - Fork, branch, code, test, submit
- Improve Documentation - Help others understand the tool
- Share Use Cases - Tell us how you use Code Explorer
MIT License - Free for personal and commercial use.
Experience the best Python code analyzer for dependency analysis:
# Install
pip install -e .
# Analyze your first project
cd /path/to/your/python/project
code-explorer analyze .
# Explore the results
code-explorer stats
code-explorer impact main.py:main
code-explorer visualize main.py --output deps.mdStart understanding your Python codebase better with this powerful dependency analysis tool!
Keywords: python code analyzer, dependency analysis tool, code graph database, python static analysis, codebase visualization, impact analysis, dependency tracker, code relationship mapping, python code exploration, software architecture analysis, best python code analyzer, free python code analyzer, python code analyzer tutorial, dependency analysis guide, code analyzer comparison