Maintainability Index
debt(d5/e5/b3/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints.tools list includes phpmetrics, sonarqube, and pdepend — all specialist static-analysis tools that must be deliberately integrated. The metric is not surfaced by default linters and is invisible without these tools, but it is fully automated once configured.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix says to run phpmetrics and target MI above 65, but low-MI files require actual refactoring of complexity and volume — not a one-line patch. common_mistakes note that low-MI files are high-value refactoring targets, implying meaningful work. The fix spans identifying and reworking multiple problematic files, though it is not necessarily a full architectural rework.
Closest to 'localised tax' (b3). The MI score applies to individual files or classes and is a reporting/tooling concern rather than a structural choice baked into the codebase. Once CI gates are set up, the ongoing burden is limited to the teams working on low-MI files rather than being a global architectural constraint that shapes every change.
Closest to 'serious trap' (t7). The misconception field explicitly states that a score above the threshold is mistakenly read as 'easy to maintain,' when in fact MI is a blended heuristic that misses poor naming, missing tests, and entangled dependencies. common_mistakes reinforce that developers game the score by adding comments, believing it improves maintainability. This directly contradicts reasonable intuitions about what a composite quality score should capture, making it a serious cognitive trap.
Also Known As
TL;DR
Explanation
The Maintainability Index (MI) was developed by Paul Oman and Jack Hagemeister and later adopted by Microsoft Visual Studio. It combines three metrics: Halstead Volume (information content of code), Cyclomatic Complexity (branching complexity), and Lines of Code. The resulting score ranges from 0 (unmaintainable) to 100 (highly maintainable), with thresholds typically at 65 (green) and 85 (very good). Tools like PHPMetrics calculate MI. Like all composite metrics, it is a heuristic — use it as a trend indicator across a codebase rather than an absolute judgment on individual methods.
Common Misconception
Why It Matters
Common Mistakes
- Not including MI in your CI quality gate — it degrades incrementally and is never urgent until it is catastrophic.
- Optimising MI score by adding comments — comments increase the score but not actual maintainability.
- Treating MI as the only quality signal — combine it with test coverage and code review to get the full picture.
- Not acting on low-MI files — they are the highest-value refactoring targets in the codebase.
Code Examples
// Low maintainability index — high complexity + long + dense:
function p($d,$f,$t,$u,$r,$c,$s){
if($d>0&&$f!==null){if($t instanceof X){foreach($r as $k=>$v){if($c[$k]??false){$s+=$v*$u;}}}}
return $d>1?$s*$d:$s+$f; // MI score would be very low — unreadable
}
// Maintainability Index = composite metric (0-100)
// Combines: Halstead Volume + Cyclomatic Complexity + Lines of Code
// > 80 = highly maintainable
// 65-80 = moderately maintainable
// < 65 = low maintainability (flag for refactoring)
// Practical improvements:
// - Reduce cyclomatic complexity (break up if/switch chains)
// - Shorten methods (< 20 lines as a guide)
// - Add docblocks (raises score)
// - Reduce Halstead volume (fewer unique operators/operands)
// Measure with PHPMetrics:
$ phpmetrics --report-html=report/ src/
// Or PHPStan + Psalm provide overlapping signals:
$ vendor/bin/phpstan analyse --level=6 src/