[{"data":1,"prerenderedAt":742},["ShallowReactive",2],{"navigation_docs":3,"-core-concepts-health-score":114,"-core-concepts-health-score-surround":737},[4,23,85,99],{"title":5,"path":6,"stem":7,"children":8},"Getting Started","\u002Fgetting-started","1.getting-started",[9,13,18],{"title":10,"path":6,"stem":11,"icon":12},"Getting started","1.getting-started\u002Findex","i-lucide-rocket",{"title":14,"path":15,"stem":16,"icon":17},"Try the demo","\u002Fgetting-started\u002Ftry-the-demo","1.getting-started\u002F1.try-the-demo","i-lucide-monitor-play",{"title":19,"path":20,"stem":21,"icon":22},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F2.quickstart","i-lucide-play",{"title":24,"path":25,"stem":26,"children":27},"Guides","\u002Fguides","2.guides",[28,31,37,42,47,53,58,63,68,74,80],{"title":24,"path":25,"stem":29,"icon":30},"2.guides\u002Findex","i-lucide-map",{"title":32,"path":33,"stem":34,"icon":35,"group":36},"Connect a GitHub repository","\u002Fguides\u002Fconnect-a-github-repository","2.guides\u002F01.connect-a-github-repository","i-lucide-git-branch","Connect a project",{"title":38,"path":39,"stem":40,"icon":41,"group":36},"Analyze a project without GitHub","\u002Fguides\u002Fanalyze-a-project-without-github","2.guides\u002F02.analyze-a-project-without-github","i-lucide-upload",{"title":43,"path":44,"stem":45,"icon":46,"group":36},"Exclude dependency scopes","\u002Fguides\u002Fexclude-dependency-scopes","2.guides\u002F04.exclude-dependency-scopes","i-lucide-filter",{"title":48,"path":49,"stem":50,"icon":51,"group":52},"Scan from GitHub Actions","\u002Fguides\u002Fscan-from-github-actions","2.guides\u002F05.scan-from-github-actions","i-lucide-workflow","Automate",{"title":54,"path":55,"stem":56,"icon":57,"group":52},"Scan from another CI","\u002Fguides\u002Fscan-from-another-ci","2.guides\u002F06.scan-from-another-ci","i-lucide-square-terminal",{"title":59,"path":60,"stem":61,"icon":62,"group":52},"Manage API keys","\u002Fguides\u002Fmanage-api-keys","2.guides\u002F07.manage-api-keys","i-lucide-key-round",{"title":64,"path":65,"stem":66,"icon":67,"group":52},"Create many projects at once","\u002Fguides\u002Fcreate-many-projects-at-once","2.guides\u002F08.create-many-projects-at-once","i-lucide-layers",{"title":69,"path":70,"stem":71,"icon":72,"group":73},"Export reports and SBOMs","\u002Fguides\u002Fexport-reports-and-sboms","2.guides\u002F11.export-reports-and-sboms","i-lucide-download","Act on the results",{"title":75,"path":76,"stem":77,"icon":78,"group":79},"Organizations and plans","\u002Fguides\u002Forganizations-and-plans","2.guides\u002F13.organizations-and-plans","i-lucide-building-2","Organization and team",{"title":81,"path":82,"stem":83,"icon":84,"group":79},"Invite your team","\u002Fguides\u002Finvite-your-team","2.guides\u002F14.invite-your-team","i-lucide-users",{"title":86,"path":87,"stem":88,"children":89},"Core Concepts","\u002Fcore-concepts","3.core-concepts",[90,94],{"title":91,"path":87,"stem":92,"icon":93},"Core concepts","3.core-concepts\u002Findex","i-lucide-lightbulb",{"title":95,"path":96,"stem":97,"icon":98},"The health score","\u002Fcore-concepts\u002Fhealth-score","3.core-concepts\u002F1.health-score","i-lucide-gauge",{"title":100,"path":101,"stem":102,"children":103},"Reference","\u002Freference","5.reference",[104,107],{"title":100,"path":101,"stem":105,"icon":106},"5.reference\u002Findex","i-lucide-book-marked",{"title":108,"path":109,"stem":110,"children":111,"icon":113},"Supported ecosystems","\u002Freference\u002Fecosystems","5.reference\u002F1.ecosystems\u002Findex",[112],{"title":108,"path":109,"stem":110,"icon":113},"i-lucide-package",{"id":115,"title":95,"body":116,"description":730,"extension":731,"links":732,"meta":733,"navigation":734,"path":96,"seo":735,"stem":97,"__hash__":736},"docs\u002F3.core-concepts\u002F1.health-score.md",{"type":117,"value":118,"toc":716},"minimark",[119,123,126,132,137,140,241,244,247,250,255,258,280,283,287,290,336,339,350,358,361,364,368,371,416,419,426,433,436,440,447,452,460,467,475,478,485,488,492,495,577,580,583,587,590,616,619,622,626,632,635,638,707,710,713],[120,121,122],"p",{},"Deptools reduces the state of your dependencies to one number between 0 and 10.\nThis page explains what goes into that number, and why a low score does not\nalways mean there is a problem.",[120,124,125],{},"The score exists at two levels. Every package in your graph is scored on its own,\nand the project gets an aggregate score, shown in the dashboard header and on the\nproject card.",[127,128],"u-color-mode-image",{"alt":129,"dark":130,"light":131},"Dashboard header showing an overall health score of 6.3 out of 10, labeled Fair","\u002Fimages\u002Fdocs\u002Fcore-concepts\u002Fhealth-score-1-overall-dark.webp","\u002Fimages\u002Fdocs\u002Fcore-concepts\u002Fhealth-score-1-overall-light.webp",[133,134,136],"h2",{"id":135},"the-six-dimensions","The six dimensions",[120,138,139],{},"The project score is built from six dimensions, each scored from 0 to 10:",[141,142,143,159],"table",{},[144,145,146],"thead",{},[147,148,149,153,156],"tr",{},[150,151,152],"th",{},"Dimension",[150,154,155],{},"What it measures",[150,157,158],{},"Source",[160,161,162,177,190,203,216,228],"tbody",{},[147,163,164,171,174],{},[165,166,167],"td",{},[168,169,170],"strong",{},"Security",[165,172,173],{},"Known vulnerabilities (CVEs) affecting the packages in your graph",[165,175,176],{},"OSV.dev",[147,178,179,184,187],{},[165,180,181],{},[168,182,183],{},"Licenses",[165,185,186],{},"How permissive the licenses in your graph are",[165,188,189],{},"Package metadata",[147,191,192,197,200],{},[165,193,194],{},[168,195,196],{},"Maintainability",[165,198,199],{},"What you have to maintain: how many dependencies a package brings, and how far behind its version is",[165,201,202],{},"Ecosystem data",[147,204,205,210,213],{},[165,206,207],{},[168,208,209],{},"Popularity",[165,211,212],{},"How widely a package is used: dependents, stars, watchers",[165,214,215],{},"Ecosystem data and GitHub",[147,217,218,223,226],{},[165,219,220],{},[168,221,222],{},"Activity",[165,224,225],{},"Whether the package is still being released and committed to",[165,227,215],{},[147,229,230,235,238],{},[165,231,232],{},[168,233,234],{},"Community",[165,236,237],{},"The people around the repository: contributors, forks, issues, pull requests",[165,239,240],{},"GitHub",[120,242,243],{},"Each dimension has its own dashboard tab, which lists the packages behind the\nnumber.",[120,245,246],{},"Four of them, Maintainability, Popularity, Activity and Community, are computed\nthe same way. Each metric behind the dimension is normalized to a 0 to 10 score.\nThe dimension score is a weighted sum of those metric scores. The weights\nare internal, and they are not the same for every metric: inside a dimension,\nsome signals say more about the health of a package than others.",[120,248,249],{},"Security and Licenses have their own formulas, described below.",[251,252,254],"h3",{"id":253},"when-the-github-repository-is-unknown","When the GitHub repository is unknown",[120,256,257],{},"Some metrics only exist if Deptools knows the GitHub repository of the package.\nMany packages do not declare one. When the repository is unknown:",[259,260,261,268,274],"ul",{},[262,263,264,267],"li",{},[168,265,266],{},"Community is skipped."," All four of its metrics are GitHub metrics, so the\npackage gets no Community score at all, and it leaves the project's Community\naverage instead of entering it as a zero.",[262,269,270,273],{},[168,271,272],{},"Activity and Popularity drop their GitHub metrics"," and redistribute their\nweight over the metrics that remain. Both dimensions are still scored from 0\nto 10, on fewer signals.",[262,275,276,279],{},[168,277,278],{},"Maintainability, Security and Licenses are unaffected."," None of them uses\nGitHub data.",[120,281,282],{},"A package without a known repository is therefore scored on what can be measured,\nnot penalized for what cannot.",[133,284,286],{"id":285},"the-security-score","The security score",[120,288,289],{},"A package starts at 10 and loses points for every known vulnerability affecting\nit:",[141,291,292,302],{},[144,293,294],{},[147,295,296,299],{},[150,297,298],{},"Severity",[150,300,301],{},"Points removed",[160,303,304,312,320,328],{},[147,305,306,309],{},[165,307,308],{},"Critical",[165,310,311],{},"8",[147,313,314,317],{},[165,315,316],{},"High",[165,318,319],{},"5",[147,321,322,325],{},[165,323,324],{},"Moderate",[165,326,327],{},"3",[147,329,330,333],{},[165,331,332],{},"Low",[165,334,335],{},"1",[120,337,338],{},"Several vulnerabilities on the same package subtract several times. The result\nnever goes below 0.",[120,340,341,342,345,346,349],{},"The project Security score ",[168,343,344],{},"is not the average of those package scores",". It answers\ntwo questions at once: ",[168,347,348],{},"how much of your graph is exposed, and how serious it is\nwhere it is exposed",".",[259,351,352,355],{},[262,353,354],{},"If no package in the graph carries a vulnerability, the score is 10.",[262,356,357],{},"Otherwise, the score falls as more packages are affected. It falls further\nwhen the affected packages have more severe vulnerabilities.",[120,359,360],{},"One critical vulnerability in a large graph and many low ones spread across it\nboth pull the score down, for different reasons. The same affected package also\ncosts more in a small graph than in a large one, since it is a bigger share of\nit. The score never goes below 0.",[120,362,363],{},"Deptools keeps a local copy of the OSV database and refreshes it every 24 hours. Security is recomputed from that copy at every analysis. Two scans of the same commit return the same Security score, unless a refresh added an advisory affecting your graph in between.",[133,365,367],{"id":366},"the-license-score","The license score",[120,369,370],{},"Every package contributes according to its most permissive license:",[141,372,373,383],{},[144,374,375],{},[147,376,377,380],{},[150,378,379],{},"License type",[150,381,382],{},"Contribution",[160,384,385,392,400,408],{},[147,386,387,390],{},[165,388,389],{},"Permissive",[165,391,335],{},[147,393,394,397],{},[165,395,396],{},"Weak copyleft",[165,398,399],{},"0.5",[147,401,402,405],{},[165,403,404],{},"Strong copyleft",[165,406,407],{},"0",[147,409,410,413],{},[165,411,412],{},"Unknown",[165,414,415],{},"Ignored, the package leaves the average",[120,417,418],{},"The average of those contributions is between 0 and 1. Multiplied by 10, it gives the base score.",[120,420,421,422,425],{},"If at least one package uses a strong copyleft license, the dimension takes an\nadditional penalty. ",[168,423,424],{},"The penalty starts at 5 points"," and grows with the share of strong copyleft packages, up to 10 when every package is under one.\nA single strong copyleft package in an otherwise permissive graph is enough to bring the Licenses dimension below 5.",[120,427,428,429,432],{},"That penalty is deliberate. Strong copyleft is a condition on how you may\ndistribute your own work, so it is a yes or no question about your graph, not a\nquality signal that degrades gradually. The ",[168,430,431],{},"Licenses tab"," names the packages\nconcerned.",[120,434,435],{},"Licenses is a project level dimension. An individual package has no license score\nof its own. Instead, a strong copyleft license lowers that package's overall\nscore directly, as described below.",[133,437,439],{"id":438},"package-score-and-project-score","Package score and project score",[120,441,442,443,446],{},"A ",[168,444,445],{},"package score"," is the average of that package's dimension scores:\nSecurity, Maintainability, Popularity, Activity and Community. A package whose\nGitHub repository is unknown averages four of them rather than five. If at least one package uses a strong copyleft license, a 0 is added to the average. Otherwise, the license score does not affect the overall score. We only penalize the presence of strong copyleft.",[127,448],{"alt":449,"dark":450,"light":451},"Package panel for jgrapht-core showing a health score of 8.2 and its five dimension bars","\u002Fimages\u002Fdocs\u002Fcore-concepts\u002Fhealth-score-2-package-dark.webp","\u002Fimages\u002Fdocs\u002Fcore-concepts\u002Fhealth-score-2-package-light.webp",[120,453,454,455,459],{},"In the panel above, ",[456,457,458],"code",{},"org.jgrapht:jgrapht-core"," scores 10.0 on Security, 9.6 on\nMaintainability, 6.9 on Popularity, 5.8 on Activity and 8.5 on Community. Their\naverage is 8.16, displayed as 8.2. Its license is weak copyleft, which adds\nnothing to the average: only strong copyleft does.",[120,461,462,463,466],{},"The ",[168,464,465],{},"project score"," is the average of the six dimension scores of the project,\nand each of those is itself computed over the packages of the graph. So the\nproject score is not the average of the package scores, and two things follow\nfrom that:",[259,468,469,472],{},[262,470,471],{},"A dimension weighs the same whatever the number of metrics behind it. Licenses\ncounts as much as Maintainability.",[262,473,474],{},"Inside a dimension, every package weighs the same. A transitive dependency you\nnever call directly weighs as much as a direct dependency, because it ships in\nyour application all the same.",[120,476,477],{},"Two populations are excluded from the averages. Your own project, the root of\nthe graph, is not a dependency and is never scored. Unresolved dependencies are\ncounted in your totals and shown in the graph, but they do not enter any\naverage. Their vulnerabilities and their license still count, since both are\nestablished without resolving the package.",[120,479,480,481,484],{},"A dimension with nothing at all to measure is shown as ",[456,482,483],{},"--",", never as 0. When\npart of your graph could not be resolved, the dashboard states how many\ndependencies the score was computed on, right under it.",[120,486,487],{},"Every score is rounded to one decimal.",[133,489,491],{"id":490},"score-labels","Score labels",[120,493,494],{},"The same bands apply to the project score, to a package score and to the colors\nin the dependency graph:",[141,496,497,510],{},[144,498,499],{},[147,500,501,504,507],{},[150,502,503],{},"Score",[150,505,506],{},"Label",[150,508,509],{},"Read it as",[160,511,512,523,534,545,556,566],{},[147,513,514,517,520],{},[165,515,516],{},"8.5 to 10",[165,518,519],{},"Excellent",[165,521,522],{},"Nothing to do here",[147,524,525,528,531],{},[165,526,527],{},"7 to 8.5",[165,529,530],{},"Good",[165,532,533],{},"Healthy, worth a look when you have time",[147,535,536,539,542],{},[165,537,538],{},"5 to 7",[165,540,541],{},"Fair",[165,543,544],{},"Something is degrading, find out what",[147,546,547,550,553],{},[165,548,549],{},"3 to 5",[165,551,552],{},"At Risk",[165,554,555],{},"Act on this before it becomes urgent",[147,557,558,561,563],{},[165,559,560],{},"0 to 3",[165,562,308],{},[165,564,565],{},"Deal with it now",[147,567,568,571,574],{},[165,569,570],{},"No value",[165,572,573],{},"Not measurable",[165,575,576],{},"Nothing could be measured, see the coverage line under the score",[120,578,579],{},"The analysis tabs use the same bands, but call the 3 to 5 band Needs Attention.",[120,581,582],{},"A score is only worth reading next to the tab that produced it. A project at 6.2\nbecause its Community dimension is low is a very different situation from a\nproject at 6.2 because its Security dimension is low, and the aggregate number\ncannot tell you which one you have.",[133,584,586],{"id":585},"why-a-score-changes","Why a score changes",[120,588,589],{},"Between two analyses of the same commit, a score can move for reasons that have\nnothing to do with your code:",[259,591,592,598,604,610],{},[262,593,594,597],{},[168,595,596],{},"A vulnerability was published or withdrawn."," Security is recomputed at every analysis, from a copy that is at most 24 hours old.",[262,599,600,603],{},[168,601,602],{},"Time passed."," Days since the last release, days since the last commit and\noutdatedness all grow on their own. A project nobody touches loses points\nslowly, which is the intended behavior: an unmaintained dependency gets riskier\nevery month.",[262,605,606,609],{},[168,607,608],{},"Ecosystem and GitHub data was refreshed."," New releases, dependent counts and\nstars are updated on their own cycle.",[262,611,612,615],{},[168,613,614],{},"Coverage changed."," A dependency that could not be resolved last time may\nresolve now, and it then enters the averages it was absent from.",[120,617,618],{},"A change in your graph does it too, of course: adding, removing or upgrading a\ndependency changes the set of packages used in each average.",[120,620,621],{},"A small change often moves nothing at all. Each metric is normalized and then\nrounded up to a whole number before it is weighted, so a value has to cross a\nboundary before anything moves. To follow the trend rather than a single reading,\ncompare a project to its own scan history.",[133,623,625],{"id":624},"scores-are-not-comparable-across-ecosystems","Scores are not comparable across ecosystems",[120,627,628,631],{},[168,629,630],{},"Every metric is normalized against reference values",", and those reference values\nare calibrated per ecosystem, because the populations are not comparable. A number of dependents that is remarkable on Maven may be quite ordinary on npm, and a graph with 800 transitive dependencies can mean something very different in each ecosystem.",[120,633,634],{},"Maven, Gradle and sbt share one calibration, since they resolve on the same\necosystem data. npm and Composer each have their own.",[120,636,637],{},"Here is the same raw value, scored in each of the three calibrations:",[141,639,640,659],{},[144,641,642],{},[147,643,644,647,650,653,656],{},[150,645,646],{},"Signal, measured on one package",[150,648,649],{},"Same value everywhere",[150,651,652],{},"Maven, Gradle, sbt",[150,654,655],{},"npm",[150,657,658],{},"Composer",[160,660,661,676,692],{},[147,662,663,666,669,672,674],{},[165,664,665],{},"GitHub stars",[165,667,668],{},"1,000 stars",[165,670,671],{},"7",[165,673,671],{},[165,675,311],{},[147,677,678,681,684,687,689],{},[165,679,680],{},"Packages that depend on it",[165,682,683],{},"20,000 dependents",[165,685,686],{},"9",[165,688,311],{},[165,690,691],{},"10",[147,693,694,697,700,703,705],{},[165,695,696],{},"Dependencies it pulls in transitively",[165,698,699],{},"22 dependencies",[165,701,702],{},"6",[165,704,319],{},[165,706,335],{},[120,708,709],{},"On the first two, more is better, and the same count is worth more in a smaller\necosystem: 20,000 packages depending on you is good on npm and exceptional on\nComposer. On the third, less is better, so the comparison inverts. Twenty two\ntransitive dependencies is a light package on the JVM, an average one on npm, and\na very heavy one on Composer, where trees are flat and a package that pulls in\nthat many is an outlier.",[120,711,712],{},"Nothing there is a judgment on the ecosystems. It is the same package, measured\nagainst the neighbors it actually has.",[120,714,715],{},"So compare a project to its own history, and to other projects in the same\necosystem. A 7.4 on npm and a 7.4 on Maven are not the same statement.",{"title":717,"searchDepth":718,"depth":718,"links":719},"",2,[720,724,725,726,727,728,729],{"id":135,"depth":718,"text":136,"children":721},[722],{"id":253,"depth":723,"text":254},3,{"id":285,"depth":718,"text":286},{"id":366,"depth":718,"text":367},{"id":438,"depth":718,"text":439},{"id":490,"depth":718,"text":491},{"id":585,"depth":718,"text":586},{"id":624,"depth":718,"text":625},"What the 0 to 10 number measures, how it is computed for a package and for a project, and why it moves.","md",null,{},{"icon":98},{"title":95,"description":730},"n2ABX3Bde36d6y-NMuG2YCOcbKKV1YII6i-WLge5BEI",[738,740],{"title":91,"path":87,"stem":92,"description":739,"icon":93,"children":-1},"What the health score measures, how it is computed, and why it moves.",{"title":100,"path":101,"stem":105,"description":741,"icon":106,"children":-1},"The ecosystems Deptools reads, and the build files it looks for in your repository.",1787263156303]