A Rust CLI that analyses a TypeScript codebase over time and produces a self-contained HTML dashboard with quality metrics, trends, and hotspots.
Named after varves — the layered sediment deposits that geologists read to understand a lake's history, one season at a time.
Varves checks out your repo at monthly intervals, scans every .ts/.tsx file, and tracks how the codebase evolves. The output is a single HTML file with interactive charts covering:
- Complexity — cognitive complexity distribution, Gini inequality, P90/P99 trends
- Code health —
anyusage,@ts-ignore/@ts-expect-errorcounts, non-null assertions, type casts - Coupling — import graph fan-in/fan-out, cycle detection, transitive import depth
- Churn — git history analysis: hotspots (churn × complexity), churn concentration, knowledge concentration
- Testing — test-to-code ratio, coverage breadth, assertion/mock density
- Trends — OLS regression, changepoint detection, bootstrap confidence intervals, rolling averages
- Groups — per-directory breakdowns with Simpson's paradox detection
The dashboard includes a statistics primer tab explaining every metric and method used.
cargo install --path .Generate a full report for the current repo:
varves reportThis produces varves-report.html — open it in a browser. First run will be slow as it creates worktrees and caches snapshots; subsequent runs reuse the cache.
varves report [OPTIONS] # Full pipeline: snapshot → churn → aggregate → HTML
varves scan [OPTIONS] <ROOT> # Single-point snapshot (per-file metrics)
varves churn [OPTIONS] # Git history churn analysis
varves snapshot [OPTIONS] # Multi-month snapshot loop only
varves aggregate [OPTIONS] # Aggregate existing snapshots only
| Flag | Default | Description |
|---|---|---|
--repo <path> |
. |
Path to the git repository |
--branch <name> |
main |
Branch to analyse |
--since <YYYY-MM> |
first commit | Earliest month |
--until <YYYY-MM> |
last complete month | Latest month |
--output <path> |
varves-report.html |
HTML output path |
--json |
Print aggregated JSON to stdout instead of HTML | |
--events <path> |
Path to events.json for timeline annotations |
|
--group-by <n> |
1 |
Directory grouping depth |
--cache-dir <path> |
.varves-cache |
Snapshot cache directory |
--parallelism <n> |
half of CPUs | Concurrent worktrees |
--exclude <glob> |
Additional exclusion patterns (repeatable) |
Single-point scan of a TypeScript project. Useful for CI or quick checks.
varves scan ./my-project --json | jq '.files | length'Annotate the timeline with team events (reorgs, migrations, major releases):
[
{ "month": "2024-06", "label": "Migrated to monorepo" },
{ "month": "2025-01", "label": "v2.0 release" }
]Pass with --events events.json. The dashboard will show segment-by-segment trends and effect sizes around each event.
These patterns are always excluded from source analysis:
**/*.test.ts,**/*.test.tsx,**/*.spec.ts,**/*.spec.tsx,**/__tests__/****/*.generated.ts,**/*.generated.tsx,**/generated/****/node_modules/**,**/dist/**,**/build/****/*.graphql.ts,**/*.graphql.tsx
Add more with --exclude <glob>.
- Snapshot loop — for each month, creates a detached git worktree at the mid-month commit and runs a full scan (parsing with oxc, computing complexity, resolving imports)
- Churn analysis — walks first-parent git history to compute per-file commits, lines added/removed, and distinct authors per month
- Aggregation — combines snapshots and churn into per-month summaries with statistical analysis (OLS trends, bootstrap CIs, changepoint detection, Gini coefficients, Pareto ratios)
- Embedding — injects the aggregated JSON into an HTML template with all images inlined, producing a fully self-contained file
Results are cached by commit hash, so re-runs only process new months.
cargo build # Build
cargo nextest run # Run tests (preferred)
cargo test # Also worksThe project uses Tracey for requirement traceability — see docs/spec/codebase-metrics.md for the full specification.