How the panels and signals work.
RepoBaron packs a lot into each tab. This page explains the mental models — what the numbers mean, why the diagrams look the way they do, and the edge cases that trip people up. Click a section in the table of contents to jump straight there.
Sessions & snapshots
A session is a saved analysis of one repo. You create one by pasting a public GitHub URL on the home page. Each session has a stable URL — bookmark it, share it, come back to it later.
A snapshot is a point-in-time slice of that session. Every time you click Refresh, RepoBaron re-fetches the repo, re-runs the full analysis pipeline, and stores the result as a new snapshot inside the same session. Old snapshots aren't deleted — they're kept so we can diff between them.
That diff drives the "Since your last visit" banner on the Overview, the Structural changes panel below it, and health-tile delta arrows. The first snapshot has nothing to compare against, so those affordances stay hidden until you refresh at least once.
Sessions are not access-controlled.Anyone with the URL can open them. The home-page list filters by an anonymous owner-id stored in your browser's localStorage — that's soft isolation, not a permission boundary. If you analyzed a sensitive repo, don't paste the session URL publicly.
Code panel
The Code tab shows your repo as a list of files sorted by file complexity (sum of McCabe complexity for every function in the file). Heavy files float to the top — those are the ones with the most branches, the most loops, the most reasons to break.
Click a file. The right side becomes Blast radius for that file (see the next section). Below the file path, you'll see a strip of chips — one per top function in the file, sorted by complexity descending. Each chip carries:
- Function name — prefixed with the class / container if there is one (
LogInService.login). - A complexity number— McCabe cyclomatic complexity. Roughly "number of independent paths through the function." 1 = straight line, 5–7 = a complex branch, 10+ = candidate for refactoring.
×Noverload marker — when N functions in the same class share a name (Java / C# overloads likelogin(String)vslogin(String, String)), they collapse into one chip. The blast-radius graph can't distinguish between them at the call-site level, so showing them as separate chips would imply more precision than we actually have.new ClassName— Java and C# name constructors after the class itself, which would otherwise render asClassName.ClassNameand read like the class is duplicated. Thenewprefix disambiguates.
Click any chip to zoom in from file-level to function-level blast radius for that specific function.
Blast radius
Blast radius answers two questions:
- Callers— "if I change this, what breaks?" The set of functions (or files) that depend on this one, transitively.
- Callees— "what does this depend on?" The set of functions this one calls, transitively.
Each result is shown grouped by hop count — 1 = direct caller / callee, 2 = caller-of-a-caller, 3 = three layers out. We cap at 3 hops by default because the noise grows faster than the signal past that.
When you see 200+instead of a precise count, we've hit the per-direction node cap. The real number is higher — the cap is there so a single "hub" function (one that calls hundreds of utilities) doesn't blow up the BFS or the UI.
File-level vs function-level.When you select a file but no specific function, blast radius unions all the functions in that file — useful for the "if I touch this file, what touches it back?" question. Click a chip in the function strip to drill down to one specific function.
Imports tab
The Imports tab is a file-level dependency canvas — every box is a file, every edge is an import (or an extends / implements / renders relationship for the languages where we extract those). Different from the Architecture tab, which works at the class level.
The layout is BFS depth-layered. Files with zero incoming edges (entry points: app routes, main scripts, public APIs) sit at the top. Leaf utilities — files that only export, never import — sit at the bottom. Layers in between form the dependency chain that connects them.
Node colors come from the file extension (TypeScript = blue, Java = orange, etc.). Edge colors come from the kind:
- Import (default) — module dependency
- Renders — JSX / TSX component reference
- Extends — class inheritance
- Implements — interface realization
Click any file to highlight neighbors — direct imports on either side stay opaque, the rest dim. Click the empty canvas to clear.
Architecture tab
The Architecture tab is a class-level diagram — one box per class / interface / enum, with their fields, methods, and relationships. Different from Imports (which is file-level): a single file can hold multiple classes, and a single class diagram skips files that have no classes at all.
The default view is the interactive canvas (ReactFlow + Dagre auto-layout). Below it is a collapsible "Show Mermaid source" disclosure — for sharing the diagram outside the app (paste into a README, a blog post, or mermaid.live).
Edge types:
- Extends — solid line, filled triangle (inheritance)
- Implements — dashed line, filled triangle (interface realization)
- Association— solid line, open arrow, with the field name as a label. Drawn whenever a class has a field whose type is another rendered class. Spring DI's
private final FooService fooServiceis the textbook case.
Generic peeling. A field of type List<Card> draws an arrow to Card, not to List. Same for Go slices ([]Foo), maps (map[K]V), pointers (*Foo), and nullable types (Foo?) across all supported languages.
Filtershandle big repos: "Hide unconnected" drops classes with zero edges (typical Props / State interface noise), and the search input filters by substring on class name. Both trigger a layout recompute, so remaining classes pack tightly instead of spreading across the original full-set bounding box.
Dependency health
The Packages tab inspects your repo's manifest files (package.json, pyproject.toml, Cargo.toml, composer.json, Gemfile, etc.) and pulls metadata from each ecosystem's registry plus security data from OSV.dev.
For each package we surface:
- Outdated — installed version is behind the latest published. Soft signal; not always actionable.
- Deprecated — the maintainer marked the package end-of-life. Strong signal; plan migration.
- Vulnerable — a CVE matches the installed version, severity from the OSV record. Hard signal; act fast.
- Abandoned— no commits / releases for an extended window (heuristic, varies by ecosystem). Soft signal; cross-check with the project's own communication.
Multi-ecosystem.One repo can have npm + PyPI + Maven manifests at the same time — each ecosystem's health is computed independently and grouped by manifest in the UI.
Untested hotspots & near-duplicates
Two actionable insight panels at the bottom of the Code tab. Both compute against your codebase as a whole, not against individual files.
Untested hotspots are functions with zero direct test callers, sorted by complexity descending. The detection is a heuristic: any file whose path ends in .test., .spec., _test., lives under __tests__/, or matches similar conventions counts as a test file. A function with at least one call edge from a test file is "tested."
The list is ordered by complexity because untested simple getters are usually fine; an untested 12-branch validator is where the bugs live. Click an item to jump to it in the file browser.
Near-duplicates are groups of functions whose AST hashes match (above a complexity floor — we ignore tiny one-line wrappers). The hash captures structure, not literal text, so two functions that differ only in variable names or formatting still match. Each group is a candidate for extracting a shared helper.
Both panels hide themselves when there's nothing to show (no test files detected, no duplicates found). Brand-new repos don't get a confusing "everything is untested" lecture.