[{"data":1,"prerenderedAt":2296},["ShallowReactive",2],{"navigation_docs":3,"-guides-dead-code":239,"-guides-dead-code-surround":2291},[4,29,94,114,184],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"Start",false,"\u002Fstart","1.start",[10,14,19,24],{"title":11,"path":7,"stem":12,"icon":13},"What jscpd finds","1.start\u002Findex","i-lucide-house",{"title":15,"path":16,"stem":17,"icon":18},"Installation","\u002Fstart\u002Finstallation","1.start\u002F2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Quickstart","\u002Fstart\u002Fquickstart","1.start\u002F3.quickstart","i-lucide-rocket",{"title":25,"path":26,"stem":27,"icon":28},"Configuration basics","\u002Fstart\u002Fconfiguration","1.start\u002F4.configuration","i-lucide-settings-2",{"title":30,"icon":6,"path":31,"stem":32,"children":33,"page":6},"Guides","\u002Fguides","2.guides",[34,39,44,49,54,59,64,69,74,79,84,89],{"title":35,"path":36,"stem":37,"icon":38},"Use jscpd in CI","\u002Fguides\u002Fci","2.guides\u002F01.ci","i-lucide-github",{"title":40,"path":41,"stem":42,"icon":43},"Pre-commit hooks","\u002Fguides\u002Fpre-commit","2.guides\u002F02.pre-commit","i-lucide-git-commit",{"title":45,"path":46,"stem":47,"icon":48},"Fail only on new duplication","\u002Fguides\u002Fbaseline","2.guides\u002F03.baseline","i-lucide-git-compare",{"title":50,"path":51,"stem":52,"icon":53},"Monorepos","\u002Fguides\u002Fmonorepos","2.guides\u002F04.monorepos","i-lucide-folder-tree",{"title":55,"path":56,"stem":57,"icon":58},"Cross-format detection","\u002Fguides\u002Fcross-format","2.guides\u002F05.cross-format","i-lucide-layers",{"title":60,"path":61,"stem":62,"icon":63},"Agents","\u002Fguides\u002Fagents","2.guides\u002F06.agents","i-lucide-cpu",{"title":65,"path":66,"stem":67,"icon":68},"Editors","\u002Fguides\u002Feditors","2.guides\u002F07.editors","i-lucide-code",{"title":70,"path":71,"stem":72,"icon":73},"Duplication over git history","\u002Fguides\u002Fhistory","2.guides\u002F08.history","i-lucide-chart-no-axes-combined",{"title":75,"path":76,"stem":77,"icon":78},"Dashboard and health score","\u002Fguides\u002Fdashboard","2.guides\u002F09.dashboard","i-lucide-layout-dashboard",{"title":80,"path":81,"stem":82,"icon":83},"Dead code","\u002Fguides\u002Fdead-code","2.guides\u002F10.dead-code","i-lucide-ghost",{"title":85,"path":86,"stem":87,"icon":88},"Comparing two codebases","\u002Fguides\u002Fcompare","2.guides\u002F11.compare","i-lucide-git-compare-arrows",{"title":90,"path":91,"stem":92,"icon":93},"Semantic clones","\u002Fguides\u002Fsemantic-clones","2.guides\u002F12.semantic-clones","i-lucide-brain-circuit",{"title":95,"icon":6,"path":96,"stem":97,"children":98,"page":6},"Concepts","\u002Fconcepts","3.concepts",[99,104,109],{"title":100,"path":101,"stem":102,"icon":103},"Types of code clones","\u002Fconcepts\u002Fclone-types","3.concepts\u002F1.clone-types","i-lucide-copy",{"title":105,"path":106,"stem":107,"icon":108},"How detection works","\u002Fconcepts\u002Fhow-detection-works","3.concepts\u002F2.how-detection-works","i-lucide-scan-search",{"title":110,"path":111,"stem":112,"icon":113},"The health score","\u002Fconcepts\u002Fhealth-score","3.concepts\u002F3.health-score","i-lucide-heart-pulse",{"title":115,"icon":6,"path":116,"stem":117,"children":118,"page":6},"Reference","\u002Freference","4.reference",[119,124,129,134,171,176,180],{"title":120,"path":121,"stem":122,"icon":123},"CLI options","\u002Freference\u002Fcli","4.reference\u002F1.cli","i-lucide-terminal",{"title":125,"path":126,"stem":127,"icon":128},"The config file","\u002Freference\u002Fconfig-file","4.reference\u002F2.config-file","i-lucide-settings",{"title":130,"path":131,"stem":132,"icon":133},"Exit codes","\u002Freference\u002Fexit-codes","4.reference\u002F3.exit-codes","i-lucide-log-out",{"title":135,"icon":6,"path":136,"stem":137,"children":138},"Reporters","\u002Freference\u002Freporters","4.reference\u002F4.reporters\u002Findex",[139,141,146,151,156,161,166],{"title":135,"path":136,"stem":137,"icon":140},"i-lucide-file-chart-column",{"title":142,"path":143,"stem":144,"icon":145},"HTML reporter","\u002Freference\u002Freporters\u002Fhtml","4.reference\u002F4.reporters\u002F2.html","i-lucide-file-code",{"title":147,"path":148,"stem":149,"icon":150},"JSON reporter","\u002Freference\u002Freporters\u002Fjson","4.reference\u002F4.reporters\u002F3.json","i-lucide-braces",{"title":152,"path":153,"stem":154,"icon":155},"Badge reporter","\u002Freference\u002Freporters\u002Fbadge","4.reference\u002F4.reporters\u002F4.badge","i-lucide-award",{"title":157,"path":158,"stem":159,"icon":160},"SARIF reporter","\u002Freference\u002Freporters\u002Fsarif","4.reference\u002F4.reporters\u002F5.sarif","i-lucide-shield-check",{"title":162,"path":163,"stem":164,"icon":165},"CodeClimate reporter","\u002Freference\u002Freporters\u002Fcodeclimate","4.reference\u002F4.reporters\u002F6.codeclimate","i-lucide-flag-triangle-right",{"title":167,"path":168,"stem":169,"icon":170},"OpenMetrics reporter","\u002Freference\u002Freporters\u002Fopenmetrics","4.reference\u002F4.reporters\u002F7.openmetrics","i-lucide-activity",{"title":172,"path":173,"stem":174,"icon":175},"Supported formats","\u002Freference\u002Fsupported-formats","4.reference\u002F5.supported-formats","i-lucide-languages",{"title":177,"path":178,"stem":179,"icon":38},"GitHub Action","\u002Freference\u002Fgithub-action","4.reference\u002F6.github-action",{"title":181,"path":182,"stem":183,"icon":68},"Rust crates","\u002Freference\u002Frust-crates","4.reference\u002F7.rust-crates",{"title":185,"icon":6,"path":186,"stem":187,"children":188,"page":6},"Project","\u002Fproject","5.project",[189,194,199,204,229,234],{"title":190,"path":191,"stem":192,"icon":193},"Changelog","\u002Fproject\u002Fchangelog","5.project\u002F1.changelog","i-lucide-scroll-text",{"title":195,"path":196,"stem":197,"icon":198},"Migrating from v4 to v5","\u002Fproject\u002Fmigration","5.project\u002F2.migration","i-lucide-arrow-right-left",{"title":200,"path":201,"stem":202,"icon":203},"jscpd v4 (TypeScript)","\u002Fproject\u002Fv4","5.project\u002F3.v4","i-simple-icons-typescript",{"title":205,"icon":6,"path":206,"stem":207,"children":208},"Benchmarks","\u002Fproject\u002Fbenchmarks","5.project\u002F4.benchmarks\u002Findex",[209,211,216,220,225],{"title":205,"path":206,"stem":207,"icon":210},"i-lucide-gauge",{"title":212,"path":213,"stem":214,"icon":215},"Detection Speed","\u002Fproject\u002Fbenchmarks\u002Fdetection-speed","5.project\u002F4.benchmarks\u002F2.detection-speed","i-lucide-zap",{"title":217,"path":218,"stem":219,"icon":58},"Multi-Format Detection","\u002Fproject\u002Fbenchmarks\u002Fcross-format","5.project\u002F4.benchmarks\u002F3.cross-format",{"title":221,"path":222,"stem":223,"icon":224},"AI Token Efficiency","\u002Fproject\u002Fbenchmarks\u002Fai-token-efficiency","5.project\u002F4.benchmarks\u002F4.ai-token-efficiency","i-lucide-sparkles",{"title":226,"path":227,"stem":228,"icon":93},"Embedding Models","\u002Fproject\u002Fbenchmarks\u002Fembedding-models","5.project\u002F4.benchmarks\u002F5.embedding-models",{"title":230,"path":231,"stem":232,"icon":233},"Research","\u002Fproject\u002Fresearch","5.project\u002F5.research","i-lucide-graduation-cap",{"title":235,"path":236,"stem":237,"icon":238},"Articles","\u002Fproject\u002Farticles","5.project\u002F6.articles","i-lucide-newspaper",{"id":240,"title":80,"body":241,"description":2282,"extension":2283,"links":2284,"meta":2285,"navigation":2286,"path":81,"seo":2287,"stem":82,"__hash__":2290},"docs\u002F2.guides\u002F10.dead-code.md",{"type":242,"value":243,"toc":2262},"minimark",[244,253,278,283,295,331,339,359,363,374,394,400,515,545,550,568,574,580,584,587,703,764,771,791,797,804,808,812,815,852,858,868,872,886,906,912,918,943,949,973,1111,1117,1131,1135,1151,1429,1449,1455,1468,1472,1479,1514,1531,1551,1557,1586,1605,1611,1615,1621,1646,1652,1673,1677,1861,1895,1898,2063,2076,2082,2085,2143,2148,2152,2165,2169,2225,2229,2258],[245,246,247,248,252],"p",{},"A clone report says what is written twice. ",[249,250,251],"code",{},"--dead-code"," asks the other question, what is never run: jscpd builds the import graph of the project from its real entry points, walks it, and reports every file, export, symbol and import the walk never reaches. Every finding is the answer to \"no entry point reaches this\", and carries a confidence that says how sure jscpd is.",[254,255,256,257,261,262,265,266,269,270,273,274,277],"note",{},"Available from jscpd ",[258,259,260],"strong",{},"5.3.0"," for JavaScript, TypeScript, JSX, TSX, Vue, Svelte, Astro and Python, ESM and CommonJS alike. Framework detection and the ",[249,263,264],{},"deadCode"," section of ",[249,267,268],{},".jscpd.json"," came in 5.3.1, Rust through ",[249,271,272],{},"--rust-diagnostics"," in 5.3.2. The analysis, basta, also ships on its own as the ",[249,275,276],{},"basta"," command.",[279,280,282],"h2",{"id":281},"run-it","Run it",[245,284,285,294],{},[286,287,291],"a",{"href":288,"rel":289},"https:\u002F\u002Fgithub.com\u002Fkucherenko\u002Fjscpd\u002Ftree\u002Fmaster\u002Ffixtures\u002Fdashboard-demo",[290],"nofollow",[249,292,293],{},"fixtures\u002Fdashboard-demo"," in the jscpd repository is a five-file TypeScript service with one legacy file nobody imports and one export nobody calls:",[296,297,303],"pre",{"className":298,"code":299,"filename":300,"language":301,"meta":302,"style":302},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","cd fixtures\u002Fdashboard-demo\njscpd . --dead-code\n","Terminal","bash","",[249,304,305,318],{"__ignoreMap":302},[306,307,310,314],"span",{"class":308,"line":309},"line",1,[306,311,313],{"class":312},"s2Zo4","cd",[306,315,317],{"class":316},"sfazB"," fixtures\u002Fdashboard-demo\n",[306,319,321,325,328],{"class":308,"line":320},2,[306,322,324],{"class":323},"sBMFI","jscpd",[306,326,327],{"class":316}," .",[306,329,330],{"class":316}," --dead-code\n",[296,332,337],{"className":333,"code":335,"language":336,"meta":302},[334],"language-text","Unused files (1)\n - src\u002Flegacy\u002Fmanifest.ts  certain 95%  10 lines\n\nUnused exports (1)\n - function src\u002Fchecks.ts:19:17 checkBatch  high 85%  3 lines\n\nFound 2 dead code findings in 5 files (14.0% of 93 lines).\nDone in 3ms\n","text",[249,338,335],{"__ignoreMap":302},[245,340,341,342,345,346,345,349,345,352,345,355,358],{},"Each finding gives the kind of declaration, its file with line and column, its name, a confidence label with the score, and the number of lines it would free. The last line counts the findings, the files the run read, and the share of their lines that is dead. A run walks with the same filters as a clone run (",[249,343,344],{},"--ignore",", ",[249,347,348],{},"--format",[249,350,351],{},".gitignore",[249,353,354],{},"--max-size",[249,356,357],{},"--follow-symlinks",") and reports through the same reporter names.",[279,360,362],{"id":361},"reading-the-output","Reading the output",[245,364,365,366,373],{},"Findings come in five categories. ",[286,367,370],{"href":368,"rel":369},"https:\u002F\u002Fgithub.com\u002Fkucherenko\u002Fjscpd\u002Ftree\u002Fmaster\u002Ffixtures\u002Fdead-code-demo",[290],[249,371,372],{},"fixtures\u002Fdead-code-demo\u002Ftypescript"," shows one of each of the four that are on by default:",[296,375,377],{"className":298,"code":376,"filename":300,"language":301,"meta":302,"style":302},"cd fixtures\u002Fdead-code-demo\u002Ftypescript\njscpd . --dead-code\n",[249,378,379,386],{"__ignoreMap":302},[306,380,381,383],{"class":308,"line":309},[306,382,313],{"class":312},[306,384,385],{"class":316}," fixtures\u002Fdead-code-demo\u002Ftypescript\n",[306,387,388,390,392],{"class":308,"line":320},[306,389,324],{"class":323},[306,391,327],{"class":316},[306,393,330],{"class":316},[296,395,398],{"className":396,"code":397,"language":336,"meta":302},[334],"Unused files (1)\n - src\u002Flegacy-export.ts  certain 95%  11 lines\n\nUnused exports (1)\n - function src\u002Finvoice.ts:21:17 renderReceipt  high 85%  3 lines\n\nUnused symbols (1)\n - function src\u002Finvoice.ts:29:10 describeTotal  certain 90%  3 lines\n\nUnused imports (1)\n - import src\u002Finvoice.ts:2:10 roundToCents  certain 100%  1 lines\n\nFound 4 dead code findings in 4 files (31.6% of 57 lines).\nDone in 4ms\n",[249,399,397],{"__ignoreMap":302},[401,402,403,419],"table",{},[404,405,406],"thead",{},[407,408,409,413,416],"tr",{},[410,411,412],"th",{},"Category",[410,414,415],{},"What it means",[410,417,418],{},"In the demo",[420,421,422,439,455,474,490],"tbody",{},[407,423,424,430,433],{},[425,426,427],"td",{},[249,428,429],{},"unused-file",[425,431,432],{},"No entry point reaches the file through the import graph",[425,434,435,438],{},[249,436,437],{},"src\u002Flegacy-export.ts",": nothing imports it. Its own exports are not listed underneath, since the file is the finding",[407,440,441,446,449],{},[425,442,443],{},[249,444,445],{},"unused-export",[425,447,448],{},"An exported name no reachable module imports",[425,450,451,454],{},[249,452,453],{},"renderReceipt",": exported from a live file, imported by nothing. Scored 85, since code outside the scan could import it",[407,456,457,462,465],{},[425,458,459],{},[249,460,461],{},"unused-symbol",[425,463,464],{},"A module-private declaration nothing reaches",[425,466,467,470,471,473],{},[249,468,469],{},"describeTotal",": its only caller is ",[249,472,453],{},", which is dead itself. Dead code reached only from dead code is dead too, which a reference count would miss",[407,475,476,481,484],{},[425,477,478],{},[249,479,480],{},"unused-import",[425,482,483],{},"An import binding with no references",[425,485,486,489],{},[249,487,488],{},"roundToCents",": imported and never mentioned again",[407,491,492,497,500],{},[425,493,494],{},[249,495,496],{},"unused-member",[425,498,499],{},"A class or enum member whose name is never read",[425,501,502,503,506,507,510,511,514],{},"Off by default. Without type information, ",[249,504,505],{},"x.render()"," could call any ",[249,508,509],{},"render"," in the project, so it is the least certain rule; ",[249,512,513],{},"--dead-code-categories all"," turns it on",[245,516,517,518,521,522,345,525,528,529,532,533,536,537,540,541,544],{},"Python has no ",[249,519,520],{},"export"," keyword, so the split between the two symbol rules comes from convention: a module-level name without a leading underscore is the module's public surface and is reported as an unused export, a name with one is an unused symbol. A ",[249,523,524],{},".vue",[249,526,527],{},".svelte"," or ",[249,530,531],{},".astro"," file is read whole, script and markup, since the markup is where a component's imports are used: a component rendered as ",[249,534,535],{},"\u003Cshipment-row>",", a function called from ",[249,538,539],{},"{{ }}",", a store read as ",[249,542,543],{},"$gaugeTheme"," all count as uses.",[546,547,549],"h3",{"id":548},"confidence","Confidence",[245,551,552,553,556,557,560,561,528,564,567],{},"Static analysis of JavaScript and Python cannot be certain, and jscpd does not pretend. Every finding carries a score from 0 to 100, labelled from ",[249,554,555],{},"low"," to ",[249,558,559],{},"certain",", and below 100 the reasons it might be wrong. The score starts from a base set by how much inference the rule needs: an import binding with no references is a fact (100), an unused file or private symbol is near-certain (95 and 90), an unused export leaves room for a caller outside the scan (85), an unused member is a guess. It then loses points for each piece of contrary evidence: a file that calls ",[249,562,563],{},"eval",[249,565,566],{},"getattr",", a decorator jscpd does not recognise, a wildcard re-export, a name that appears in a string, a file in the scan that did not parse. A file whose own path ends a string literal somewhere, the way a framework names a file it loads by itself, loses 40 points, which takes it under the default floor.",[245,569,570,573],{},[249,571,572],{},"--min-confidence"," sets the floor, 60 by default. With the floor at 0, every finding shows with its reasons:",[296,575,578],{"className":576,"code":577,"language":336,"meta":302},[334],"Unused exports (2)\n - function screens\u002Faccount\u002Floyalty.screen.js:9:17 legacyPromoCode  low 25%  3 lines\n   ↳ part of the package's published API\n - function screens\u002Fcheckout\u002Ftotals.js:5:17 splitBetween  high 85%  3 lines\n",[249,579,577],{"__ignoreMap":302},[279,581,583],{"id":582},"how-jscpd-decides-what-is-dead","How jscpd decides what is dead",[245,585,586],{},"Everything rests on the entry points. They come from five places, in decreasing order of authority:",[588,589,590,629,659,693,696],"ol",{},[591,592,593,594,597,598,345,601,345,604,345,607,345,610,613,614,617,618,597,621,624,625,628],"li",{},"Manifests. ",[249,595,596],{},"package.json","'s ",[249,599,600],{},"main",[249,602,603],{},"module",[249,605,606],{},"bin",[249,608,609],{},"exports",[249,611,612],{},"files"," and ",[249,615,616],{},"scripts","; ",[249,619,620],{},"pyproject.toml",[249,622,623],{},"[project.scripts]"," and entry-point tables. A manifest that names a built file (",[249,626,627],{},".\u002Fdist\u002Findex.js",") is mapped back to the source it was built from.",[591,630,631,632,635,636,639,640,642,643,650,651,654,655,658],{},"Frameworks. A router that turns ",[249,633,634],{},"pages\u002F"," into URLs, a runtime that loads ",[249,637,638],{},"plugins\u002F"," whole, a test runner that loads a setup file. jscpd detects a framework per directory from its config file, from the dependencies of ",[249,641,596],{}," or from its section there, and every framework that matches is in force at once. The built-in table, ",[286,644,647],{"href":645,"rel":646},"https:\u002F\u002Fgithub.com\u002Fkucherenko\u002Fjscpd\u002Fblob\u002Fv5.4.0\u002Frust\u002Fcrates\u002Fbasta\u002Fframeworks.yaml",[290],[249,648,649],{},"frameworks.yaml",", holds 56 definitions in jscpd 5.4.0, Django, Alembic and Scrapy among them. A definition also lists the names its framework reads out of the code, ",[249,652,653],{},"getServerSideProps"," in a Next page or ",[249,656,657],{},"ngOnInit"," on an Angular class, and a declaration under one of them is used. The console report names what it detected.",[591,660,661,662,345,665,345,668,345,671,613,673,676,677,680,681,684,685,688,689,692],{},"Conventions. ",[249,663,664],{},"src\u002Findex.ts",[249,666,667],{},"__main__.py",[249,669,670],{},"manage.py",[249,672,634],{},[249,674,675],{},"app\u002F"," routes, ",[249,678,679],{},"*.config.ts",", a ",[249,682,683],{},".d.ts"," ambient declaration, a file with a shebang, a Python ",[249,686,687],{},"if __name__ == \"__main__\""," guard, and a package's ",[249,690,691],{},"__init__.py",".",[591,694,695],{},"Scripts. A shell script, a CI workflow, a Makefile or a Dockerfile in the tree that names a source file by path runs it, copies it or ships it, so that file is an entry point.",[591,697,698,699,702],{},"You. ",[249,700,701],{},"--entry \u003Cglob>",", repeatable, adds entry points and never removes one.",[245,704,705,706,613,709,712,713,716,717,712,720,723,724,712,727,730,731,734,735,345,738,345,741,613,744,747,748,613,751,754,755,345,757,759,760,763],{},"Import paths are then read the way the project's own build reads them: aliases from ",[249,707,708],{},"tsconfig.json",[249,710,711],{},"jsconfig.json"," ",[249,714,715],{},"paths",", from ",[249,718,719],{},"vite.config.*",[249,721,722],{},"resolve.alias"," and from ",[249,725,726],{},"svelte.config.*",[249,728,729],{},"kit.alias"," (SvelteKit's ",[249,732,733],{},"$lib"," and WXT's ",[249,736,737],{},"@",[249,739,740],{},"~",[249,742,743],{},"@@",[249,745,746],{},"~~"," need no config, since the files that declare them are generated); globs such as ",[249,749,750],{},"import(`.\u002Fpages\u002F${name}.vue`)",[249,752,753],{},"import.meta.glob('.\u002Flocales\u002F*.js')",", which reach every file their pattern matches; workspace package names, which resolve through that package's own ",[249,756,596],{},[249,758,609],{}," subpath by subpath, preferring source conditions over ",[249,761,762],{},".\u002Fdist",". Two breadth-first walks follow, one over import edges to decide which files run and one over reference edges to decide which declarations run.",[245,765,766,767,770],{},"The Vite project in the demo keeps half its graph in ",[249,768,769],{},"vite.config.js",", a template-literal import and a glob, and still reports only what is dead:",[296,772,774],{"className":298,"code":773,"filename":300,"language":301,"meta":302,"style":302},"cd fixtures\u002Fdead-code-demo\u002Fbundler\njscpd . --dead-code\n",[249,775,776,783],{"__ignoreMap":302},[306,777,778,780],{"class":308,"line":309},[306,779,313],{"class":312},[306,781,782],{"class":316}," fixtures\u002Fdead-code-demo\u002Fbundler\n",[306,784,785,787,789],{"class":308,"line":320},[306,786,324],{"class":323},[306,788,327],{"class":316},[306,790,330],{"class":316},[296,792,795],{"className":793,"code":794,"language":336,"meta":302},[334],"Frameworks: vite\n\nUnused files (1)\n - src\u002Flegacy\u002Fcourier-api.js  certain 95%  5 lines\n\nUnused exports (1)\n - function src\u002Frouter.js:8:17 preloadPage  high 85%  3 lines\n\nFound 2 dead code findings in 9 files (12.5% of 64 lines).\nDone in 7ms\n",[249,796,794],{"__ignoreMap":302},[245,798,799,800,803],{},"Test files are always entry points, so a test file is never unused. Dead code inside one is off by default, and ",[249,801,802],{},"--include-tests"," turns it on. An export only the test suite imports is reported separately, and says so.",[279,805,807],{"id":806},"common-tasks","Common tasks",[546,809,811],{"id":810},"keep-only-what-jscpd-is-sure-of","Keep only what jscpd is sure of",[245,813,814],{},"Raising the floor is the first thing to try on a codebase that does something unusual. On the whole demo folder, nine small projects, the exported names drop out at 90, since those are the findings a caller outside the scan could invalidate:",[296,816,818],{"className":298,"code":817,"filename":300,"language":301,"meta":302,"style":302},"cd fixtures\u002Fdead-code-demo\njscpd . --dead-code\njscpd . --dead-code --min-confidence 90\n",[249,819,820,827,835],{"__ignoreMap":302},[306,821,822,824],{"class":308,"line":309},[306,823,313],{"class":312},[306,825,826],{"class":316}," fixtures\u002Fdead-code-demo\n",[306,828,829,831,833],{"class":308,"line":320},[306,830,324],{"class":323},[306,832,327],{"class":316},[306,834,330],{"class":316},[306,836,838,840,842,845,848],{"class":308,"line":837},3,[306,839,324],{"class":323},[306,841,327],{"class":316},[306,843,844],{"class":316}," --dead-code",[306,846,847],{"class":316}," --min-confidence",[306,849,851],{"class":850},"sbssI"," 90\n",[296,853,856],{"className":854,"code":855,"language":336,"meta":302},[334],"Found 26 dead code findings in 47 files (30.7% of 449 lines).\nFound 19 dead code findings in 47 files (26.3% of 449 lines).\n",[249,857,855],{"__ignoreMap":302},[245,859,860,863,864,867],{},[249,861,862],{},"--dead-code-categories"," narrows the report to the categories you want to act on, for example ",[249,865,866],{},"--dead-code-categories unused-file,unused-import"," for the two that are safest to delete.",[546,869,871],{"id":870},"tell-jscpd-about-files-a-framework-starts","Tell jscpd about files a framework starts",[245,873,874,877,878,881,882,885],{},[249,875,876],{},"fixtures\u002Fdead-code-demo\u002Fframeworks\u002Fcustom"," runs on an in-house router that mounts every ",[249,879,880],{},"screens\u002F**\u002F*.screen.js",". With no description of the router (move its ",[249,883,884],{},"basta.frameworks.yaml"," out of the folder to see this), every screen reads as dead:",[296,887,889],{"className":298,"code":888,"filename":300,"language":301,"meta":302,"style":302},"cd fixtures\u002Fdead-code-demo\u002Fframeworks\u002Fcustom\njscpd . --dead-code\n",[249,890,891,898],{"__ignoreMap":302},[306,892,893,895],{"class":308,"line":309},[306,894,313],{"class":312},[306,896,897],{"class":316}," fixtures\u002Fdead-code-demo\u002Fframeworks\u002Fcustom\n",[306,899,900,902,904],{"class":308,"line":320},[306,901,324],{"class":323},[306,903,327],{"class":316},[306,905,330],{"class":316},[296,907,910],{"className":908,"code":909,"language":336,"meta":302},[334],"Unused files (3)\n - screens\u002Faccount\u002Floyalty.screen.js  certain 95%  19 lines\n - screens\u002Fcheckout\u002Fbasket.screen.js  certain 95%  9 lines\n - screens\u002Fcheckout\u002Ftotals.js  certain 95%  7 lines\n\nFound 3 dead code findings in 5 files (68.6% of 51 lines).\nDone in 4ms\n",[249,911,909],{"__ignoreMap":302},[245,913,914,917],{},[249,915,916],{},"--entry"," says it once for a run:",[296,919,921],{"className":298,"code":920,"filename":300,"language":301,"meta":302,"style":302},"jscpd . --dead-code --entry 'screens\u002F**\u002F*.screen.js'\n",[249,922,923],{"__ignoreMap":302},[306,924,925,927,929,931,934,938,940],{"class":308,"line":309},[306,926,324],{"class":323},[306,928,327],{"class":316},[306,930,844],{"class":316},[306,932,933],{"class":316}," --entry",[306,935,937],{"class":936},"sMK4o"," '",[306,939,880],{"class":316},[306,941,942],{"class":936},"'\n",[296,944,947],{"className":945,"code":946,"language":336,"meta":302},[334],"Unused exports (1)\n - function screens\u002Fcheckout\u002Ftotals.js:5:17 splitBetween  high 85%  3 lines\n\nFound 1 dead code findings in 5 files (5.9% of 51 lines).\nDone in 5ms\n",[249,948,946],{"__ignoreMap":302},[245,950,951,952,954,955,345,958,961,962,965,966,968,969,972],{},"A description of the framework says it for good, in the shape of the built-in table. ",[249,953,884],{}," (or ",[249,956,957],{},".yml",[249,959,960],{},".json",") in the working directory is picked up on its own; the demo's is detected by the ",[249,963,964],{},"kioskRouter"," section of its ",[249,967,596],{},", roots the screens, and names ",[249,970,971],{},"guard"," as a function the router calls, so that export is never reported:",[296,974,978],{"className":975,"code":976,"filename":884,"language":977,"meta":302,"style":302},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","frameworks:\n  - name: kiosk-router\n    detect:\n      packageJsonKeys: [kioskRouter]\n    variables:\n      screensDir: screens\n    entry:\n      - \"${screensDir}\u002F**\u002F*.screen.js\"\n    globals:\n      - names: [guard]\n        files: [\"${screensDir}\u002F**\u002F*.screen.js\"]\n","yaml",[249,979,980,989,1003,1010,1026,1034,1045,1053,1068,1076,1092],{"__ignoreMap":302},[306,981,982,986],{"class":308,"line":309},[306,983,985],{"class":984},"swJcz","frameworks",[306,987,988],{"class":936},":\n",[306,990,991,994,997,1000],{"class":308,"line":320},[306,992,993],{"class":936},"  -",[306,995,996],{"class":984}," name",[306,998,999],{"class":936},":",[306,1001,1002],{"class":316}," kiosk-router\n",[306,1004,1005,1008],{"class":308,"line":837},[306,1006,1007],{"class":984},"    detect",[306,1009,988],{"class":936},[306,1011,1013,1016,1018,1021,1023],{"class":308,"line":1012},4,[306,1014,1015],{"class":984},"      packageJsonKeys",[306,1017,999],{"class":936},[306,1019,1020],{"class":936}," [",[306,1022,964],{"class":316},[306,1024,1025],{"class":936},"]\n",[306,1027,1029,1032],{"class":308,"line":1028},5,[306,1030,1031],{"class":984},"    variables",[306,1033,988],{"class":936},[306,1035,1037,1040,1042],{"class":308,"line":1036},6,[306,1038,1039],{"class":984},"      screensDir",[306,1041,999],{"class":936},[306,1043,1044],{"class":316}," screens\n",[306,1046,1048,1051],{"class":308,"line":1047},7,[306,1049,1050],{"class":984},"    entry",[306,1052,988],{"class":936},[306,1054,1056,1059,1062,1065],{"class":308,"line":1055},8,[306,1057,1058],{"class":936},"      -",[306,1060,1061],{"class":936}," \"",[306,1063,1064],{"class":316},"${screensDir}\u002F**\u002F*.screen.js",[306,1066,1067],{"class":936},"\"\n",[306,1069,1071,1074],{"class":308,"line":1070},9,[306,1072,1073],{"class":984},"    globals",[306,1075,988],{"class":936},[306,1077,1079,1081,1084,1086,1088,1090],{"class":308,"line":1078},10,[306,1080,1058],{"class":936},[306,1082,1083],{"class":984}," names",[306,1085,999],{"class":936},[306,1087,1020],{"class":936},[306,1089,971],{"class":316},[306,1091,1025],{"class":936},[306,1093,1095,1098,1100,1102,1105,1107,1109],{"class":308,"line":1094},11,[306,1096,1097],{"class":984},"        files",[306,1099,999],{"class":936},[306,1101,1020],{"class":936},[306,1103,1104],{"class":936},"\"",[306,1106,1064],{"class":316},[306,1108,1104],{"class":936},[306,1110,1025],{"class":936},[296,1112,1115],{"className":1113,"code":1114,"language":336,"meta":302},[334],"Frameworks: kiosk-router\n\nUnused exports (1)\n - function screens\u002Fcheckout\u002Ftotals.js:5:17 splitBetween  high 85%  3 lines\n\nFound 1 dead code findings in 5 files (5.9% of 51 lines).\nDone in 6ms\n",[249,1116,1114],{"__ignoreMap":302},[245,1118,1119,1120,1123,1124,1127,1128,1130],{},"A screen is an entry point, so its exports are reported only with ",[249,1121,1122],{},"--include-entry-exports",", at a low confidence that says why: the ",[249,1125,1126],{},"legacyPromoCode"," finding in the confidence example above comes from this project, and ",[249,1129,971],{}," is not next to it.",[546,1132,1134],{"id":1133},"put-the-settings-in-jscpdjson","Put the settings in .jscpd.json",[245,1136,1137,1138,1140,1141,613,1144,1146,1147,1150],{},"A project that keeps a config says its dead-code settings there once, in a section called ",[249,1139,264],{}," (",[249,1142,1143],{},"dead-code",[249,1145,276],{}," are the same key). ",[249,1148,1149],{},"fixtures\u002Fdead-code-demo\u002Fconfig"," has one with a confidence floor, a dead-code budget, an entry glob and an inline framework definition:",[296,1152,1156],{"className":1153,"code":1154,"filename":268,"language":1155,"meta":302,"style":302},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"threshold\": 10,\n  \"deadCode\": {\n    \"minConfidence\": 90,\n    \"threshold\": 40,\n    \"entry\": [\"tools\u002F*.js\"],\n    \"frameworks\": [\n      {\n        \"name\": \"job-runner\",\n        \"detect\": { \"packageJsonKeys\": [\"jobRunner\"] },\n        \"entry\": [\"jobs\u002F**\u002F*.job.js\"],\n        \"globals\": [{ \"names\": [\"schedule\"], \"files\": [\"jobs\u002F**\u002F*.job.js\"] }]\n      }\n    ]\n  }\n}\n","json",[249,1157,1158,1163,1182,1195,1212,1227,1250,1263,1268,1289,1327,1348,1405,1411,1417,1423],{"__ignoreMap":302},[306,1159,1160],{"class":308,"line":309},[306,1161,1162],{"class":936},"{\n",[306,1164,1165,1168,1172,1174,1176,1179],{"class":308,"line":320},[306,1166,1167],{"class":936},"  \"",[306,1169,1171],{"class":1170},"spNyl","threshold",[306,1173,1104],{"class":936},[306,1175,999],{"class":936},[306,1177,1178],{"class":850}," 10",[306,1180,1181],{"class":936},",\n",[306,1183,1184,1186,1188,1190,1192],{"class":308,"line":837},[306,1185,1167],{"class":936},[306,1187,264],{"class":1170},[306,1189,1104],{"class":936},[306,1191,999],{"class":936},[306,1193,1194],{"class":936}," {\n",[306,1196,1197,1200,1203,1205,1207,1210],{"class":308,"line":1012},[306,1198,1199],{"class":936},"    \"",[306,1201,1202],{"class":323},"minConfidence",[306,1204,1104],{"class":936},[306,1206,999],{"class":936},[306,1208,1209],{"class":850}," 90",[306,1211,1181],{"class":936},[306,1213,1214,1216,1218,1220,1222,1225],{"class":308,"line":1028},[306,1215,1199],{"class":936},[306,1217,1171],{"class":323},[306,1219,1104],{"class":936},[306,1221,999],{"class":936},[306,1223,1224],{"class":850}," 40",[306,1226,1181],{"class":936},[306,1228,1229,1231,1234,1236,1238,1240,1242,1245,1247],{"class":308,"line":1036},[306,1230,1199],{"class":936},[306,1232,1233],{"class":323},"entry",[306,1235,1104],{"class":936},[306,1237,999],{"class":936},[306,1239,1020],{"class":936},[306,1241,1104],{"class":936},[306,1243,1244],{"class":316},"tools\u002F*.js",[306,1246,1104],{"class":936},[306,1248,1249],{"class":936},"],\n",[306,1251,1252,1254,1256,1258,1260],{"class":308,"line":1047},[306,1253,1199],{"class":936},[306,1255,985],{"class":323},[306,1257,1104],{"class":936},[306,1259,999],{"class":936},[306,1261,1262],{"class":936}," [\n",[306,1264,1265],{"class":308,"line":1055},[306,1266,1267],{"class":936},"      {\n",[306,1269,1270,1273,1276,1278,1280,1282,1285,1287],{"class":308,"line":1070},[306,1271,1272],{"class":936},"        \"",[306,1274,1275],{"class":850},"name",[306,1277,1104],{"class":936},[306,1279,999],{"class":936},[306,1281,1061],{"class":936},[306,1283,1284],{"class":316},"job-runner",[306,1286,1104],{"class":936},[306,1288,1181],{"class":936},[306,1290,1291,1293,1296,1298,1300,1303,1305,1308,1310,1312,1314,1316,1319,1321,1324],{"class":308,"line":1078},[306,1292,1272],{"class":936},[306,1294,1295],{"class":850},"detect",[306,1297,1104],{"class":936},[306,1299,999],{"class":936},[306,1301,1302],{"class":936}," {",[306,1304,1061],{"class":936},[306,1306,1307],{"class":984},"packageJsonKeys",[306,1309,1104],{"class":936},[306,1311,999],{"class":936},[306,1313,1020],{"class":936},[306,1315,1104],{"class":936},[306,1317,1318],{"class":316},"jobRunner",[306,1320,1104],{"class":936},[306,1322,1323],{"class":936},"]",[306,1325,1326],{"class":936}," },\n",[306,1328,1329,1331,1333,1335,1337,1339,1341,1344,1346],{"class":308,"line":1094},[306,1330,1272],{"class":936},[306,1332,1233],{"class":850},[306,1334,1104],{"class":936},[306,1336,999],{"class":936},[306,1338,1020],{"class":936},[306,1340,1104],{"class":936},[306,1342,1343],{"class":316},"jobs\u002F**\u002F*.job.js",[306,1345,1104],{"class":936},[306,1347,1249],{"class":936},[306,1349,1351,1353,1356,1358,1360,1363,1365,1368,1370,1372,1374,1376,1379,1381,1384,1386,1388,1390,1392,1394,1396,1398,1400,1402],{"class":308,"line":1350},12,[306,1352,1272],{"class":936},[306,1354,1355],{"class":850},"globals",[306,1357,1104],{"class":936},[306,1359,999],{"class":936},[306,1361,1362],{"class":936}," [{",[306,1364,1061],{"class":936},[306,1366,1367],{"class":984},"names",[306,1369,1104],{"class":936},[306,1371,999],{"class":936},[306,1373,1020],{"class":936},[306,1375,1104],{"class":936},[306,1377,1378],{"class":316},"schedule",[306,1380,1104],{"class":936},[306,1382,1383],{"class":936},"],",[306,1385,1061],{"class":936},[306,1387,612],{"class":984},[306,1389,1104],{"class":936},[306,1391,999],{"class":936},[306,1393,1020],{"class":936},[306,1395,1104],{"class":936},[306,1397,1343],{"class":316},[306,1399,1104],{"class":936},[306,1401,1323],{"class":936},[306,1403,1404],{"class":936}," }]\n",[306,1406,1408],{"class":308,"line":1407},13,[306,1409,1410],{"class":936},"      }\n",[306,1412,1414],{"class":308,"line":1413},14,[306,1415,1416],{"class":936},"    ]\n",[306,1418,1420],{"class":308,"line":1419},15,[306,1421,1422],{"class":936},"  }\n",[306,1424,1426],{"class":308,"line":1425},16,[306,1427,1428],{"class":936},"}\n",[296,1430,1432],{"className":298,"code":1431,"filename":300,"language":301,"meta":302,"style":302},"cd fixtures\u002Fdead-code-demo\u002Fconfig\njscpd . --dead-code\n",[249,1433,1434,1441],{"__ignoreMap":302},[306,1435,1436,1438],{"class":308,"line":309},[306,1437,313],{"class":312},[306,1439,1440],{"class":316}," fixtures\u002Fdead-code-demo\u002Fconfig\n",[306,1442,1443,1445,1447],{"class":308,"line":320},[306,1444,324],{"class":323},[306,1446,327],{"class":316},[306,1448,330],{"class":316},[296,1450,1453],{"className":1451,"code":1452,"language":336,"meta":302},[334],"Using config from .jscpd.json\nFrameworks: job-runner\n\nUnused files (1)\n - src\u002Flegacy-zpl.js  certain 95%  7 lines\n\nFound 1 dead code findings in 5 files (14.0% of 50 lines).\nDone in 5ms\n",[249,1454,1452],{"__ignoreMap":302},[245,1456,1457,1458,1461,1462,1464,1465,692],{},"jscpd looks for the config in the working directory, so the same project scanned from its parent folder (",[249,1459,1460],{},"jscpd config --dead-code",") reports four findings: the job the runner starts, the tool run by hand, the legacy module and an export nothing calls. A flag beats the section for one run, and the section configures the mode without switching it on: a plain ",[249,1463,324],{}," in that directory still looks for clones unless the section says ",[249,1466,1467],{},"\"enabled\": true",[546,1469,1471],{"id":1470},"read-rust-dead-code-from-the-compiler","Read Rust dead code from the compiler",[245,1473,1474,1475,1478],{},"jscpd does not parse Rust. The compiler already finds unused code with real name resolution, trait dispatch and macro expansion behind it, so jscpd reads the output of ",[249,1476,1477],{},"cargo check"," and reports it next to everything else. jscpd never runs cargo itself, because that would execute the project's build scripts:",[296,1480,1482],{"className":298,"code":1481,"filename":300,"language":301,"meta":302,"style":302},"cargo check --all-targets --message-format=json | jscpd . --dead-code --rust-diagnostics -\n",[249,1483,1484],{"__ignoreMap":302},[306,1485,1486,1489,1492,1495,1498,1501,1504,1506,1508,1511],{"class":308,"line":309},[306,1487,1488],{"class":323},"cargo",[306,1490,1491],{"class":316}," check",[306,1493,1494],{"class":316}," --all-targets",[306,1496,1497],{"class":316}," --message-format=json",[306,1499,1500],{"class":936}," |",[306,1502,1503],{"class":323}," jscpd",[306,1505,327],{"class":316},[306,1507,844],{"class":316},[306,1509,1510],{"class":316}," --rust-diagnostics",[306,1512,1513],{"class":316}," -\n",[245,1515,1516,1519,1520,1523,1524,1526,1527,1530],{},[249,1517,1518],{},"fixtures\u002Fdead-code-demo\u002Frust"," commits that output as ",[249,1521,1522],{},"cargo-check.json",", and its ",[249,1525,268],{}," names the file as ",[249,1528,1529],{},"rustDiagnostics",", so a plain run works without a Rust toolchain:",[296,1532,1534],{"className":298,"code":1533,"filename":300,"language":301,"meta":302,"style":302},"cd fixtures\u002Fdead-code-demo\u002Frust\njscpd . --dead-code\n",[249,1535,1536,1543],{"__ignoreMap":302},[306,1537,1538,1540],{"class":308,"line":309},[306,1539,313],{"class":312},[306,1541,1542],{"class":316}," fixtures\u002Fdead-code-demo\u002Frust\n",[306,1544,1545,1547,1549],{"class":308,"line":320},[306,1546,324],{"class":323},[306,1548,327],{"class":316},[306,1550,330],{"class":316},[296,1552,1555],{"className":1553,"code":1554,"language":336,"meta":302},[334],"Using config from .jscpd.json\n\nUnused symbols (4)\n - function src\u002Flayout.rs:5:8 render_return  certain 100%  3 lines\n - function src\u002Flib.rs:15:4 reprint  certain 100%  3 lines\n - class src\u002Flib.rs:19:8 Roll  certain 100%  4 lines\n - variable src\u002Flib.rs:30:7 MAX_PER_ROLL  certain 100%  1 lines\n\nUnused imports (1)\n - import src\u002Flib.rs:3:5 HashMap  certain 100%  1 lines\n\nUnused members (1)\n - method src\u002Flib.rs:25:8 fits  certain 100%  3 lines\n\nFound 6 dead code findings in 2 files (40.5% of 37 lines).\nDone in 5ms\n",[249,1556,1554],{"__ignoreMap":302},[245,1558,1559,1560,1563,1564,1567,1568,1570,1571,1574,1575,1578,1579,613,1582,1585],{},"Every finding is at 100%, because the compiler resolved every name. ",[249,1561,1562],{},"dead_code"," on a function, struct, enum, constant or trait is an unused symbol, on a method, field or variant an unused member, and ",[249,1565,1566],{},"unused_imports"," is an unused import. The compiler's span covers only the name, so jscpd reads each item's real size from the source. A finding from a test target is reported only with ",[249,1569,802],{},", at 85%. jscpd reports only what the compiler reports: a ",[249,1572,1573],{},"pub"," item of a library is never reported, code behind a feature the check did not build is reported as dead, and ",[249,1576,1577],{},"#[allow(dead_code)]"," hides an item from both. The same flag works with ",[249,1580,1581],{},"--dashboard",[249,1583,1584],{},"--health",", so a Rust project gets its health badge from the check it already runs:",[296,1587,1589],{"className":298,"code":1588,"filename":300,"language":301,"meta":302,"style":302},"jscpd . --health --rust-diagnostics cargo-check.json\n",[249,1590,1591],{"__ignoreMap":302},[306,1592,1593,1595,1597,1600,1602],{"class":308,"line":309},[306,1594,324],{"class":323},[306,1596,327],{"class":316},[306,1598,1599],{"class":316}," --health",[306,1601,1510],{"class":316},[306,1603,1604],{"class":316}," cargo-check.json\n",[296,1606,1609],{"className":1607,"code":1608,"language":336,"meta":302},[334],"Health  B   74\u002F100  █████████████████▊░░░░░░  30 lines of code (XS)\n  duplication   76  █████████░░░  0.0% in rust (no data)\n  dead code     70  ████████▌░░░  40.5%\n  complexity    75  █████████░░░  0.0% in complex files\n",[249,1610,1608],{"__ignoreMap":302},[546,1612,1614],{"id":1613},"gate-it-in-ci","Gate it in CI",[245,1616,1617,1620],{},[249,1618,1619],{},"--threshold"," in a dead-code run is a budget for the dead share. The demo service at 14% fails a budget of 10 and exits 1:",[296,1622,1624],{"className":298,"code":1623,"filename":300,"language":301,"meta":302,"style":302},"cd fixtures\u002Fdashboard-demo\njscpd . --dead-code --threshold 10\n",[249,1625,1626,1632],{"__ignoreMap":302},[306,1627,1628,1630],{"class":308,"line":309},[306,1629,313],{"class":312},[306,1631,317],{"class":316},[306,1633,1634,1636,1638,1640,1643],{"class":308,"line":320},[306,1635,324],{"class":323},[306,1637,327],{"class":316},[306,1639,844],{"class":316},[306,1641,1642],{"class":316}," --threshold",[306,1644,1645],{"class":850}," 10\n",[296,1647,1650],{"className":1648,"code":1649,"language":336,"meta":302},[334],"ERROR: basta found too much dead code (14.0%) over threshold (10.0%)\nFound 2 dead code findings in 5 files (14.0% of 93 lines).\n",[249,1651,1649],{"__ignoreMap":302},[245,1653,1654,1657,1658,1661,1662,1665,1666,1669,1670,1672],{},[249,1655,1656],{},"--exit-code"," exits 1 (or the code you give) on any finding, ",[249,1659,1660],{},"--fail-on-empty"," exits 1 when the run read no file, and ",[249,1663,1664],{},"--reporters sarif"," writes ",[249,1667,1668],{},"basta-report.sarif"," for GitHub code scanning. ",[286,1671,35],{"href":36}," shows the workflows.",[279,1674,1676],{"id":1675},"options","Options",[401,1678,1679,1695],{},[404,1680,1681],{},[407,1682,1683,1686,1689,1692],{},[410,1684,1685],{},"Flag",[410,1687,1688],{},"Config key",[410,1690,1691],{},"What it does",[410,1693,1694],{},"Default",[420,1696,1697,1714,1745,1765,1783,1799,1815,1841],{},[407,1698,1699,1703,1708,1711],{},[425,1700,1701],{},[249,1702,251],{},[425,1704,1705],{},[249,1706,1707],{},"deadCode.enabled",[425,1709,1710],{},"Find dead code instead of clones",[425,1712,1713],{},"off",[407,1715,1716,1721,1726,1742],{},[425,1717,1718],{},[249,1719,1720],{},"--dead-code-categories \u003CLIST>",[425,1722,1723],{},[249,1724,1725],{},"deadCode.categories",[425,1727,1728,345,1730,345,1732,345,1734,345,1736,1738,1739],{},[249,1729,429],{},[249,1731,445],{},[249,1733,461],{},[249,1735,480],{},[249,1737,496],{},", or ",[249,1740,1741],{},"all",[425,1743,1744],{},"the first four",[407,1746,1747,1752,1757,1760],{},[425,1748,1749],{},[249,1750,1751],{},"--min-confidence \u003CN>",[425,1753,1754],{},[249,1755,1756],{},"deadCode.minConfidence",[425,1758,1759],{},"Drop findings below this confidence, 0 to 100",[425,1761,1762],{},[249,1763,1764],{},"60",[407,1766,1767,1772,1777,1780],{},[425,1768,1769],{},[249,1770,1771],{},"--entry \u003CGLOB>",[425,1773,1774],{},[249,1775,1776],{},"deadCode.entry",[425,1778,1779],{},"Add entry points; the flag repeats",[425,1781,1782],{},"manifests, frameworks, conventions and scripts",[407,1784,1785,1789,1794,1797],{},[425,1786,1787],{},[249,1788,802],{},[425,1790,1791],{},[249,1792,1793],{},"deadCode.includeTests",[425,1795,1796],{},"Report dead code inside test, fixture and example files",[425,1798,1713],{},[407,1800,1801,1805,1810,1813],{},[425,1802,1803],{},[249,1804,1122],{},[425,1806,1807],{},[249,1808,1809],{},"deadCode.includeEntryExports",[425,1811,1812],{},"Report exports of entry-point files, which are usually a public API",[425,1814,1713],{},[407,1816,1817,1822,1827,1838],{},[425,1818,1819],{},[249,1820,1821],{},"--rust-diagnostics \u003CFILE>",[425,1823,1824],{},[249,1825,1826],{},"deadCode.rustDiagnostics",[425,1828,1829,1830,1833,1834,1837],{},"A file of ",[249,1831,1832],{},"cargo check --message-format=json"," output, or ",[249,1835,1836],{},"-"," for stdin (5.3.2+)",[425,1839,1840],{},"none",[407,1842,1843,1848,1856,1859],{},[425,1844,1845],{},[249,1846,1847],{},"--threshold \u003CN>",[425,1849,1850,1853,1854],{},[249,1851,1852],{},"deadCode.threshold",", else the top-level ",[249,1855,1171],{},[425,1857,1858],{},"Exit 1 when the dead share is over N percent",[425,1860,1840],{},[245,1862,1863,1864,1867,1868,1871,1872,1874,1875,1878,1879,1881,1882,1885,1886,1889,1890,613,1892,692],{},"The section also takes ",[249,1865,1866],{},"minLines"," (the smallest declaration worth reporting), ",[249,1869,1870],{},"ignore"," (globs skipped in a dead-code run only), ",[249,1873,985],{}," (definitions inline), ",[249,1876,1877],{},"frameworksConfig"," (a file of definitions instead of ",[249,1880,884],{},"), ",[249,1883,1884],{},"framework"," (frameworks to take as present) and ",[249,1887,1888],{},"noFrameworks",". A misspelled key inside the section is reported by name and the section is left out. The full option list is in ",[286,1891,120],{"href":121},[286,1893,1894],{"href":126},"Configuration file",[279,1896,135],{"id":1897},"reporters",[401,1899,1900,1910],{},[404,1901,1902],{},[407,1903,1904,1907],{},[410,1905,1906],{},"Reporter",[410,1908,1909],{},"Output",[420,1911,1912,1926,1936,1984,1996,2026,2038,2051],{},[407,1913,1914,1919],{},[425,1915,1916],{},[249,1917,1918],{},"console",[425,1920,1921,1922,1925],{},"The list above; ",[249,1923,1924],{},"console-full"," adds the source lines of each finding",[407,1927,1928,1933],{},[425,1929,1930],{},[249,1931,1932],{},"ai",[425,1934,1935],{},"One line per finding with its confidence and message, for an agent",[407,1937,1938,1942],{},[425,1939,1940],{},[249,1941,1155],{},[425,1943,1944,1947,1948,1951,1952,345,1955,345,1958,345,1960,345,1963,345,1966,345,1969,345,1972,345,1975,613,1977,1980,1981],{},[249,1945,1946],{},"basta-report.json",": ",[249,1949,1950],{},"findings[]"," with ",[249,1953,1954],{},"category",[249,1956,1957],{},"path",[249,1959,1275],{},[249,1961,1962],{},"symbolKind",[249,1964,1965],{},"language",[249,1967,1968],{},"start",[249,1970,1971],{},"end",[249,1973,1974],{},"lines",[249,1976,548],{},[249,1978,1979],{},"message",", and ",[249,1982,1983],{},"statistics",[407,1985,1986,1991],{},[425,1987,1988],{},[249,1989,1990],{},"sarif",[425,1992,1993,1995],{},[249,1994,1668],{},", with the category as the rule id, for code scanning",[407,1997,1998,2012],{},[425,1999,2000,345,2003,345,2006,345,2009],{},[249,2001,2002],{},"markdown",[249,2004,2005],{},"html",[249,2007,2008],{},"csv",[249,2010,2011],{},"xml",[425,2013,2014,345,2017,345,2020,345,2023],{},[249,2015,2016],{},"basta-report.md",[249,2018,2019],{},"basta-report.html",[249,2021,2022],{},"basta-report.csv",[249,2024,2025],{},"basta-report.xml",[407,2027,2028,2033],{},[425,2029,2030],{},[249,2031,2032],{},"badge",[425,2034,2035],{},[249,2036,2037],{},"basta-badge.svg",[407,2039,2040,2045],{},[425,2041,2042],{},[249,2043,2044],{},"codeclimate",[425,2046,2047,2050],{},[249,2048,2049],{},"basta-codeclimate.json",", for GitLab code quality",[407,2052,2053,2058],{},[425,2054,2055],{},[249,2056,2057],{},"openmetrics",[425,2059,2060],{},[249,2061,2062],{},"basta-report.txt",[245,2064,2065,2066,1140,2069,2072,2073,2075],{},"The files go to ",[249,2067,2068],{},"--output",[249,2070,2071],{},".\u002Freport"," by default). The ",[249,2074,1983],{}," object of the JSON report for the demo service:",[296,2077,2080],{"className":2078,"code":2079,"language":336,"meta":302},[334],"\"statistics\": {\n    \"files\": 5,\n    \"unparsed\": 0,\n    \"reachableFiles\": 4,\n    \"symbols\": 22,\n    \"entryPoints\": 1,\n    \"byCategory\": [\n        {\n            \"category\": \"unused-file\",\n            \"count\": 1,\n            \"lines\": 10\n        },\n        {\n            \"category\": \"unused-export\",\n            \"count\": 1,\n            \"lines\": 3\n        }\n    ],\n    \"deadLines\": 13,\n    \"totalLines\": 93,\n    \"percentage\": 13.978494623655912,\n    \"detectionDate\": \"2026-10-06T14:49:51.755Z\"\n}\n",[249,2081,2079],{"__ignoreMap":302},[279,2083,130],{"id":2084},"exit-codes",[401,2086,2087,2097],{},[404,2088,2089],{},[407,2090,2091,2094],{},[410,2092,2093],{},"Code",[410,2095,2096],{},"When",[420,2098,2099,2109,2130],{},[407,2100,2101,2106],{},[425,2102,2103],{},[249,2104,2105],{},"0",[425,2107,2108],{},"The run finished and no gate tripped. Findings alone do not change the code",[407,2110,2111,2116],{},[425,2112,2113],{},[249,2114,2115],{},"1",[425,2117,2118,2119,528,2121,2123,2124,2126,2127,2129],{},"The dead share is over ",[249,2120,1619],{},[249,2122,1852],{},"; a finding was made with ",[249,2125,1656],{},"; no file was read with ",[249,2128,1660],{},"; an option is wrong, such as an unknown category",[407,2131,2132,2137],{},[425,2133,2134],{},[249,2135,2136],{},"N",[425,2138,2139,2142],{},[249,2140,2141],{},"--exit-code N"," and at least one finding",[245,2144,2145,2147],{},[286,2146,130],{"href":131}," covers the rest.",[279,2149,2151],{"id":2150},"in-the-health-score","In the health score",[245,2153,2154,2155,2158,2159,2161,2162,2164],{},"The health score has a dead-code dimension: the dead lines divided by the lines the analysis could read, scored on a half-life of 7.5% after the size adjustment. The dimension weighs as much as the share of the code jscpd could read, so in a project that is 30% TypeScript and 70% Go it counts for 0.3, and when that share is under 5% the dimension is left out and named ",[249,2156,2157],{},"n\u002Fa",". Rust counts as read once you pass ",[249,2160,272],{},". ",[286,2163,110],{"href":111}," has the formula and a worked example.",[279,2166,2168],{"id":2167},"limits","Limits",[2170,2171,2172,2182,2188,2199,2210,2216,2219],"ul",{},[591,2173,2174,2175,2178,2179,2181],{},"An import jscpd cannot resolve is a missing edge, and the file behind it is reported as unused at high confidence. That happens with an alias declared somewhere jscpd does not read, a glob it cannot expand, a file a framework it does not know loads by name, and an ",[249,2176,2177],{},"import()"," whose path is computed at runtime. ",[249,2180,916],{},", a framework definition or a higher confidence floor are the fixes, in that order of precision.",[591,2183,2184,2185,2187],{},"No type inference: a member access matches members by name across the whole project, which is why ",[249,2186,496],{}," is opt-in.",[591,2189,2190,2191,2194,2195,2198],{},"No runtime resolution: ",[249,2192,2193],{},"getattr(obj, name)",", an ",[249,2196,2197],{},"import(expr)"," with no static directory to expand over, and a module object passed as a parameter are recorded as uncertainty and lower confidence.",[591,2200,2201,2202,2205,2206,2209],{},"No Markdown or MDX: an ",[249,2203,2204],{},"import"," written in an ",[249,2207,2208],{},".mdx"," page is not an edge, so a component used only from content reads as unused.",[591,2211,2212,2213,2215],{},"An export used only inside its own file is not reported. The ",[249,2214,520],{}," keyword is then unnecessary, and the code is alive.",[591,2217,2218],{},"Only the five categories: unused dependencies, unused files in other languages and unused local variables are out of scope. Rust has no unused-file or unused-export category, since the compiler reports neither.",[591,2220,2221,2222,692],{},"A file that fails to parse lowers the confidence of every finding in the run, because its references are unknown. The console trailer names such files, up to ten, and the JSON report lists them under ",[249,2223,2224],{},"statistics.unparsedFiles",[279,2226,2228],{"id":2227},"related","Related",[2170,2230,2231,2236,2241,2249],{},[591,2232,2233,2235],{},[286,2234,75],{"href":76}," shows the largest findings next to duplication and complexity.",[591,2237,2238,2240],{},[286,2239,110],{"href":111}," explains how the dead share becomes a sub-score.",[591,2242,2243,2245,2246,692],{},[286,2244,65],{"href":66}," fades dead code in the editor through ",[249,2247,2248],{},"jscpd --lsp",[591,2250,2251,2253,2254,2257],{},[286,2252,60],{"href":61}," covers the ",[249,2255,2256],{},"codebase-refactoring"," skill, which removes dead code as its second pass.",[2259,2260,2261],"style",{},"html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":302,"searchDepth":320,"depth":320,"links":2263},[2264,2265,2268,2269,2276,2277,2278,2279,2280,2281],{"id":281,"depth":320,"text":282},{"id":361,"depth":320,"text":362,"children":2266},[2267],{"id":548,"depth":837,"text":549},{"id":582,"depth":320,"text":583},{"id":806,"depth":320,"text":807,"children":2270},[2271,2272,2273,2274,2275],{"id":810,"depth":837,"text":811},{"id":870,"depth":837,"text":871},{"id":1133,"depth":837,"text":1134},{"id":1470,"depth":837,"text":1471},{"id":1613,"depth":837,"text":1614},{"id":1675,"depth":320,"text":1676},{"id":1897,"depth":320,"text":135},{"id":2084,"depth":320,"text":130},{"id":2150,"depth":320,"text":2151},{"id":2167,"depth":320,"text":2168},{"id":2227,"depth":320,"text":2228},"Find the files, exports, symbols and imports nothing runs with jscpd --dead-code, in JavaScript, TypeScript, Python and compiler-checked Rust, each finding with a confidence.","md",null,{},{"icon":83},{"title":2288,"description":2289},"Dead code detection with jscpd --dead-code","jscpd --dead-code walks a project's import graph from its real entry points and reports unused files, exports, symbols, imports and members with a confidence score, for JavaScript, TypeScript, Vue, Svelte, Astro, Python and Rust.","kTZXwKEuFio76jfck4Af50I88aO7CP8GN3YXLrmYBo4",[2292,2294],{"title":75,"path":76,"stem":77,"description":2293,"icon":78,"children":-1},"One screen with a project's size, duplication, complexity and dead code from jscpd --dashboard, and the health badge alone from jscpd --health.",{"title":85,"path":86,"stem":87,"description":2295,"icon":88,"children":-1},"Measure a port to another language, or check two implementations of one app for parity, with jscpd --compare: example reports in the console, JSON, Markdown and HTML, and how to read each one.",1791302982807]