Drift provides two related metrics: coverage (completeness) and health (completeness + accuracy combined).
Coverage measures the percentage of exports that have a JSDoc description.
drift coverage
An export is "documented" if it has:
description (the main JSDoc comment body), OR@internal)coverage = documented_exports / total_exports * 100
{
"score": 88,
"documented": 22,
"total": 25,
"undocumented": ["parseConfig", "formatOutput", "validateInput"]
}
Exports whose declaration lives outside the analyzed program don't count against you. If an export's source resolves to <external> (or it's package-only, with no local file), it's bucketed out of the denominator instead of counting as undocumented:
{
"score": 94,
"documented": 142,
"total": 151,
"external": 12
}
This shows up as summary.externalExports in the SDK, coverage.external in CLI JSON, and a +N external (not resolvable here) note in human-readable output.
Set a minimum coverage threshold:
drift coverage --min 80
Or in config:
{
"coverage": {
"min": 80
}
}
Exit code 1 if coverage is below the threshold.
Ratchet mode prevents coverage from regressing. When enabled, the effective minimum is the higher of coverage.min and the historical watermark (highest coverage ever recorded).
{
"coverage": {
"min": 70,
"ratchet": true
}
}
If your coverage once hit 85%, the effective threshold becomes 85% even though min is 70%. This ensures coverage only goes up.
drift list --undocumented
Returns all exports missing JSDoc descriptions.
Health is a weighted composite of two signals:
drift health
Note: bare drift runs scan (which includes health), not health.
completeness = documented / total * 100
accuracy = (documented - drifted_exports) / documented * 100
health = completeness * 0.5 + accuracy * 0.5
Where drifted_exports is the count of unique exports with at least one lint issue (not the total issue count).
A package with 25 exports, 22 documented, and 4 exports with drift issues:
completeness = 22/25 * 100 = 88%
accuracy = (22-4)/22 * 100 = 82%
health = 88 * 0.5 + 82 * 0.5 = 85%
{
"health": 85,
"completeness": 88,
"accuracy": 82,
"totalExports": 25,
"documented": 22,
"undocumented": 3,
"drifted": 4,
"issues": [
{ "export": "parseConfig", "issue": "@param 'options' type mismatch" },
{ "export": "createClient", "issue": "@returns type mismatch" }
],
"packageName": "my-lib",
"packageVersion": "1.0.0",
"min": 80
}
drift health --min 80
Or use drift scan --min 80 which includes health checking.
| Range | Status |
|---|---|
| 80-100 | Good |
| 60-79 | Needs work |
| 0-59 | Poor |
drift scan Combines Bothdrift scan runs coverage, lint, prose drift, and health in a single pass:
drift scan --min 80
Its health field is the same computation as drift health. The coverage.score field matches drift coverage. Use scan when you want everything at once; use coverage or health individually for focused checks.
All three commands support --all:
drift coverage --all
drift health --all
drift scan --all
Batch output includes per-package scores and aggregate totals. Private packages are excluded by default; add --private to include them.
drift list --undocumented.drift lint. Common issues are param name mismatches and stale return types after refactoring.See Drift Detection for the full list of drift types and how to interpret lint output.