What Is Code Health? A Practical Guide to the 25 Markers

Raghav ChamadiyaUpdated 9 min read
Compared in this post: repowise and
  • CodeScene
  • SonarQube Server
On this page

Code health is a per-file estimate of how much friction the next change will create, built from code structure, coupling, test signal and git history. repowise scores every file from 1 to 10 using 25 markers that feed the headline defect-risk score (it registers 53 detectors in total; the rest feed the separate maintainability and performance signals). A low score means look here first, not this is broken.

Part of the code health guide.

What is code health?

Code health answers one question: where will future work slow down, and why? A file can be short but tangled. A module can be clean but surrounded by fragile callers. A repo can have good tests and still be hard to change because a few files absorb most edits. A useful measure needs four ingredients:

  1. Structure: how hard the code is to read and reason about.
  2. Coupling: what depends on it, and what it depends on.
  3. Test signal: whether changes are guarded by meaningful tests.
  4. Churn signal: whether history says the file keeps changing, breaking or losing its owner.

Other tools measure parts of this. SonarQube Server reports maintainability, reliability, duplication, coverage and complexity metrics, and CodeScene defines Code Health as an aggregate of 25+ factors on a 1 to 10 scale (as of October 2026). repowise combines the same four ingredients in one per-file score and keeps the reason beside the number.

Why averages hide the files that matter

A repo-wide average can improve while the riskiest file gets worse. If one module scores 9 and another scores 2, the mean looks fine. CodeScene makes the same point: a single KPI is not enough, and averages can hide low-scoring files that carry risk.

repowise reports three repository figures instead of one: average health, hotspot health (hotspot files only) and the worst performer. Bands are absolute, so a 6.2 means the same in every repository.

BandScoreMeaning
Excellent8.5 and aboveLow risk, easy to change
Good7.0 to 8.5Sound; nothing demands attention
Fair5.5 to 7.0Rising complexity or process risk
Needs work4.0 to 5.5Worth scheduling
At riskunder 4.0Where defects concentrate

Scroll the table sideways to see every column.

Each file starts at 10. Every finding deducts its severity times its marker weight, deductions are capped per family so no single family dominates, and the result is clamped to 1 to 10.

A repowise file page showing a code health score of 8.3 out of 10 in the Good band, with lines, symbols, dependents and test coverage beside it
A repowise file page showing a code health score of 8.3 out of 10 in the Good band, with lines, symbols, dependents and test coverage beside it

A file page in repowise's own repository: the score, its band, and the dependency and test context beside it.

The 25 markers

The markers fall into five families: complexity, design and duplication, coupling, test signal and churn. The grouping matters more than the exact thresholds. Full detector roster: code health architecture docs.

Complexity

MarkerFlags
Complex methodFunctions with cyclomatic complexity (CCN) of 9 or more
Nested complexityFunctions nested more than 4 levels deep
Bumpy roadSeveral medium-depth nesting humps side by side
Large methodLong bodies that also carry branching
God classA class of 200+ NLOC with 15+ methods and a brain method
Complex conditionalConditions glued from three or more boolean operators
Function hotspotFunctions that are both complex and frequently modified

Scroll the table sideways to see every column.

Design and duplication

These deduct at half weight in the defect score, because on their own they proved weak bug predictors. The maintainability signal counts them in full.

MarkerFlags
Brain method70+ lines, CCN 9+, in a file many others import
Low cohesionA class whose methods split into groups sharing no fields (LCOM4 of 2 or more)
Long parameter listFive or more raw parameters that want to be one object
DRY violationDuplicated code, weighted up when copies change together
Error handlingSwallowed or catch-all handlers, Rust unwrap and panic!, ignored Go errors

Scroll the table sideways to see every column.

Coupling

MarkerFlags
Co-change scatterA file coupled to many distinct co-change partners (shotgun surgery)
Knowledge lossA bus factor of 1 where that author has left or makes under 20% of recent commits

Scroll the table sideways to see every column.

Test signal

MarkerFlags
Untested hotspotA churning, widely imported file with no meaningful coverage
Coverage gapSignificant uncovered surface in a non-trivial file (needs a coverage report)
Coverage gradientA continuous deduction proportional to the uncovered fraction
Large assertion blockOne test with 15+ consecutive assertions
Duplicated assertion blockCopy-pasted assertion sequences across tests

Scroll the table sideways to see every column.

Churn signal

MarkerFlags
Churn riskChurn normalised by file size, a stronger predictor than raw churn
Change entropyChanges scattered across wide, noisy commits
Code age volatilityDormant code that is suddenly modified again
Developer congestion5+ contributors, top-quarter churn, nobody owning half
Ownership riskMany drive-by authors, none above 40%
Prior defectRecent bug-fix history, the cheapest predictor of the next fix

Scroll the table sideways to see every column.

History amplifies code risk; it does not stand alone. Git history costs a file at most 1.0 point, plus one point for each point its code-shape findings deduct, up to 3.5. A simple file that changes often reads as busy, not broken, and never drops below 9.0 from history alone.

Does the score predict bugs?

Yes, measurably. repowise scored files at a historical commit and checked them against the next six months of bug fixes, with nothing after that commit feeding the score. ROC AUC was 0.74 across 21 repositories and 9 languages, +0.10 AUC over ranking by recent churn, and 0.76 to 0.78 on the external PROMISE/jEdit corpus. Against CodeScene on the same files, repowise surfaced 2.3x the defects under a 20%-of-lines review budget. Method and reports: benchmarks.

From score to decision

A per-file score is useful when it says what would make the file safer to touch. In repowise:

bash
repowise init             # full index; scores every file, no LLM key
repowise health           # fix first, KPIs, lowest-scoring files
repowise health --trend   # the last 10 snapshots
repowise next             # the short cross-layer to-do list

Agents get the same data through the get_health MCP tool, per repo or per file. Then triage the lowest files:

PatternLikely fix
High complexity, low churnRefactor only when you next touch it
High complexity, high churnSchedule a dedicated cleanup
Widely imported, low coverageAdd characterization tests first, then split
Many co-change partnersRevisit module boundaries
Knowledge loss on an active filePair on it and write down the decisions

Scroll the table sideways to see every column.

The fix-first list ranks one unit of work per item with the first edit, expected gain, effort and the tests to run. For a larger refactor, see refactoring priorities by impact per effort.

Reading a trend

A falling score says more than a low one. Every init and update stores a snapshot, and repowise alerts on declining (a fall of 0.5 or more against five snapshots back), predicted decline (three falls in a row) and history drag (the git-history half moved, so nothing in the code needs action). A file that dropped from 8 to 6 in two months is an active feature under pressure. A file flat at 6 for a year is known debt. More: declining code health trends.

FAQ

What is code health in software engineering?
Code health is a measure of how costly future changes to code will be. It combines structure, coupling, testing and change history so teams can spot risk before it turns into slow delivery.
What are code health metrics?
They are the measurements used to estimate maintainability and defect risk: complexity, nesting, coupling, coverage, churn, co-change and ownership. repowise turns them into 25 markers that move a per-file score.
What is a good code health score?
In repowise, 7.0 and above is Good and 8.5 and above is Excellent. Under 4.0 is At risk, where defects concentrate. Bands are absolute, so scores compare across repositories.
Is a code health score enough on its own?
No. A score is a summary, not a diagnosis. The markers show whether the cause is complexity, coupling, missing tests or churn, and that decides the fix.
Does repowise need an LLM key to score code health?
No. Scoring reads the parse tree, the dependency graph and git history, and runs inside repowise init and repowise update.
How do I improve code health without a big refactor?
Start with the top fix-first item. Add a test around current behavior, make one extraction, and re-score with repowise update, which re-scores only changed files.