Skip to main content

codaviz

A lightweight CLI that analyzes code complexity and emits a single, self-contained, interactive HTML report — a simpler, local alternative to SonarQube for spotting where to refactor. Python works out of the box; JavaScript/TypeScript, Go, Ruby, Rust, Java, and PHP are supported via an optional tree-sitter extra.

Point it at a repo and it ranks complexity hotspots, draws a treemap (sized by lines of code, colored by a metric you pick), lets you drill into any module to read its functions and source, and flags circular imports and over-threshold functions. No server, no database, no network — the report is one HTML file you can open offline or email to a teammate.

codaviz interactive report — treemap, top-modules chart, and per-function drill-down with cyclomatic + cognitive complexity

Full documentation lives in docs/src/ (built with Zensical: make docs).

Quick start

codaviz is a uv project. From a checkout:

uv sync                          # install (Python analysis)
uv sync --extra treesitter       # + JS/TS, Go, Ruby, Rust, Java, PHP
uv run codaviz /path/to/project  # writes ./report.html
open report.html                 # (macOS; use xdg-open on Linux)

Try it on codaviz itself:

uv run codaviz . && open report.html

To install it as a standalone command:

uv tool install .                  # Python only
uv tool install ".[treesitter]"    # all languages
# then, anywhere: codaviz /path/to/project

Usage

codaviz [OPTIONS] [PATHS...]

  PATHS                Project directories to analyze (default: current dir).
                       Pass several to merge a workspace into one report.

  -f, --format         html | json | csv          (default: html)
  -o, --output FILE    Output file
                       (html → report.html; json/csv → stdout unless set)
      --no-source      Omit embedded source snippets (smaller, shareable report)
      --version        Show version and exit
  -h, --help           Show help and exit

Examples:

codaviz ~/src/myapp                     # interactive report.html
codaviz ~/src/myapp -o myapp.html       # custom output path
codaviz ~/src/myapp --no-source -o share.html   # no source embedded
codaviz ~/src/myapp -f json > data.json # raw entity data
codaviz ~/src/myapp -f csv  > data.csv  # one row per package/module/function
codaviz packages/*                      # merge a workspace into one report

The report

  • Treemap — packages and modules as nested tiles, sized by lines of code and colored by the selected metric (packages by their aggregate over all descendants; greener = better). Click a package to zoom in; a depth control caps how many levels show at once so large trees stay readable.
  • Metric selector — switch between Maintainability index (default), max/total cyclomatic, max/total cognitive, and lines of code; the treemap, bar chart, and table all re-rank instantly.
  • Hotspots table & bar chart — ranked by the selected metric, with LOC / MI / max & total cyclomatic / max & total cognitive / function count. A Modules / Packages toggle switches between per-module rows and package aggregates — so a complex package still stands out even when it's split into many small modules.
  • Function detail — click a tile, bar, or row to see that module's functions, each with a CC (cyclomatic) and Cog (cognitive) badge, line number, and source snippet. Functions over either threshold get a "consider extracting" / "hard to follow" hint.
  • Circular imports — modules that import each other (statically detected) are listed as cycles.

What gets analyzed

Inside a git repo, codaviz analyzes the source files git knows about — tracked and uncommitted — while honoring .gitignore (so .venv, build output, and ignored trees are skipped). Outside a repo, it walks the directory. Each file is dispatched by extension to the analyzer for its language. On top of that it always skips common noise: virtualenvs, caches, build/, dist/, node_modules/, site-packages/, migrations/, and test files (tests/, test_*.py, *_test.py, conftest.py) unless you opt in.

Languages

Language Metrics Extensions
Python CC, cognitive, MI, SLOC .py
JavaScript / TypeScript CC, SLOC .js .jsx .mjs .cjs .ts .tsx .mts .cts
Go CC, SLOC .go
Ruby CC, SLOC .rb
Rust CC, SLOC .rs
Java CC, SLOC .java
PHP CC, SLOC .php .phtml

Python works with no extra dependencies. Every other language uses tree-sitter and needs the optional treesitter extra (pip install codaviz[treesitter] / uv sync --extra treesitter); without it, those files are simply skipped. Maintainability index is Python-only and per-language cognitive complexity is planned, so non-Python modules report cyclomatic + SLOC and the report opens on a cyclomatic lens. A single report can mix languages.

Adding a language. codaviz uses a pluggy plugin system: a package contributes analyzers over the codaviz hook namespace and registers via the codaviz entry-point group. A new tree-sitter language is a small config subclass (its grammar + which node kinds count) — no new parsing code.

Metrics

Metric Meaning Direction
Cyclomatic (CC) McCabe complexity — branch/loop count + 1. Per function. Matches Ruff's C901 / python -m mccabe. higher = worse
Cognitive (Cog) SonarSource cognitive complexity — penalises nesting, ignores shorthand humans read easily. The better "how hard to understand" signal. Per function. higher = worse
Maintainability index (MI) radon's 0–100 composite (≥20 = A/good, 10–19 = B, <10 = C). Per module. Kept as the familiar number. lower = worse
SLOC Source lines of code (excludes blanks/comments). — (used for tile size)

For Python, cyclomatic complexity comes from mccabe (so the numbers match Ruff), cognitive from cognitive_complexity, MI + SLOC from radon, and circular imports from a static ast import graph (no code is executed). For other languages, cyclomatic + SLOC are computed from the tree-sitter syntax tree — McCabe-family (decision points + 1), not tied to any specific external tool, so numbers are internally consistent per language but not claimed to match gocyclo/PMD/ESLint.

Configuration

Optional [tool.codaviz] table in the analyzed project's pyproject.toml:

[tool.codaviz]
exclude = ["generated/*.py", "vendor/**"]  # extra glob patterns to skip
max-complexity = 15                         # cyclomatic threshold for hints
max-cognitive = 15                          # cognitive threshold for hints
treemap-depth = 2                           # initial treemap depth (0 = all levels)
include-tests = false                       # set true to analyze test files too

Known limitations

  • Nested defs: closures and methods of function-local classes are folded into their enclosing function's score rather than listed separately — matching how Ruff/mccabe report the outer function.
  • Circular imports: resolution favors false negatives over false positives. src/ layouts, implicit namespace packages, and relative imports resolve correctly (names are computed relative to the detected source root); dynamic or conditional imports are not tracked.
  • Color scale: the badness ramp is green→amber→red with a "better → worse" legend and a numeric table as non-color channels; a fully colorblind-safe palette is a planned option.

Development

make test     # uv run pytest
make lint     # ruff check + format check + type checks
make format   # ruff format + autofix

The test suite spans unit / integration / end-to-end tiers, including in-browser execution of the report's JavaScript via Node.

Status

Latest release 0.6.0; multi-language + plugin support has landed on main (see CHANGES.md, Unreleased). Stable and usable: hotspots, treemap (package-level aggregates, tunable depth), drill-down, cyclomatic + cognitive complexity, maintainability index, circular imports, threshold hints, src/-layout and multi-root/workspace analysis, seven languages behind a pluggy plugin seam, and HTML/JSON/CSV output. Planned next (rough order): a shared cognitive-complexity walker for the tree-sitter languages, churn-weighted hotspots (complexity × git change-frequency), and coupling metrics (afferent/efferent, instability). See notes/ for the vision, spec, and plans.

Non-goals

Security scanning (use Bandit), runtime profiling (use cProfile/scalene), and test coverage (use pytest-cov) are out of scope — codaviz focuses on structural complexity.

License

Apache License 2.0 — see LICENSE.

Metadata

Release files for codaviz 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for codaviz 0.7.0
File Size Uploaded
codaviz-0.7.0.tar.gz 377.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for codaviz 0.7.0
File Interpreter ABI Platform
codaviz-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 767.5 kB

Release files / codaviz-0.7.0.tar.gz

Download URL codaviz-0.7.0.tar.gz
Size 377.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2d7a786168cef542817e4e6fc24c15b7f338baba280f67a0a3423be96f6c0950
BLAKE2b-256 checksum
How to use checksums
788667b7c53dc01bf28603b9485f1e0e70bb3ff8d9a1fed6442aa59d9d433b30
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.12 {"installer":{"name":"uv","version":"0.12.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / codaviz-0.7.0-py3-none-any.whl

Download URL codaviz-0.7.0-py3-none-any.whl
Size 390.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dd120752d91942d06cbf8cebc71c71975fbbaf2b441a0fa3185b1d728c1a0e2a
BLAKE2b-256 checksum
How to use checksums
a85f89b54b59ed13b96682a8038515946772091aa01b82ca190da28d71ec1856
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.12 {"installer":{"name":"uv","version":"0.12.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files

0.6.0

2 release files

0.5.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page