[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81862":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":13,"stars7d":13,"stars30d":13,"stars90d":13,"forks30d":13,"starsTrendScore":13,"compositeScore":15,"rankGlobal":10,"rankLanguage":10,"license":16,"archived":17,"fork":17,"defaultBranch":18,"hasWiki":17,"hasPages":19,"topics":20,"createdAt":10,"pushedAt":10,"updatedAt":21,"readmeContent":22,"aiSummary":23,"trendingCount":13,"starSnapshotCount":13,"syncStatus":24,"lastSyncTime":25,"discoverSource":26},81862,"codescythe","perplexityai\u002Fcodescythe","perplexityai","Codescythe is a focused TypeScript dead-code analyzer and remover","https:\u002F\u002Fperplexityai.github.io\u002Fcodescythe",null,"Rust",23,0,1,40,"Apache License 2.0",false,"main",true,[],"2026-06-12 04:01:35","# Codescythe\n\nCodescythe is a focused TypeScript and JavaScript dead-code analyzer and\nremover inspired by [Knip](https:\u002F\u002Fknip.dev), scoped to entry\u002Fproject graph\nanalysis and unused source exports\u002Ffiles. It intentionally avoids Knip's\nframework plugin surface.\n\nIt exists for TypeScript-heavy JavaScript codebases that want a smaller, more\npredictable cleanup tool: start from known entry points, follow the\nimport\u002Fexport graph, and identify project files or exported symbols that nothing\nreachable uses. Many dead-code tools grow into broad framework integration\nlayers; Codescythe chooses a narrower contract so the analysis is easier to\nreason about, test, and run as part of automated cleanup.\n\nThe goal is not to replace Knip for every framework-aware audit. Codescythe is\nfor the common package and monorepo maintenance job where the project boundary is\nalready known and the useful answer is deterministic: which source files and\nexports are unused, and which of those removals can be applied safely.\n\n## Codescythe And Knip\n\nCodescythe takes a deliberately smaller slice of Knip's problem space.\n\n| | Knip | Codescythe |\n| --- | --- | --- |\n| Primary scope | Broad JavaScript and TypeScript project hygiene: unused files, exports, dependencies, binaries, unresolved imports, and related issue types. | Focused TypeScript\u002FJavaScript dead-code analysis: unused project files, unused exports, unresolved imports, and supported removals. |\n| Project discovery | Infers more from package metadata, workspaces, scripts, framework config, and built-in plugins. | Starts from explicit `entry` and `project` config, then follows the import\u002Fexport graph. |\n| Framework awareness | Designed for framework and tool integrations through plugins and compilers. | Intentionally avoids a framework plugin surface. |\n| Best fit | Comprehensive audits where framework config, dependency hygiene, and workspace conventions matter. | Deterministic cleanup jobs where the source boundary is already known and repeatable graph behavior matters more than integration breadth. |\n\n## Benchmarks\n\nThe benchmark suite runs Codescythe and Knip against pinned real-world\nTypeScript-heavy repositories fetched through Bazel. Representative local runs\nproduced:\n\n| Fixture | Benchmarked files | Codescythe | Knip |\n| --- | ---: | ---: | ---: |\n| `microsoft\u002Fvscode` | 9,398 | 1.11s | 4.22s |\n| `grafana\u002Fgrafana` | 8,358 | 833.2ms | 9.51s |\n| `elastic\u002Fkibana` | 90,931 | 13.61s | 43.04s |\n| `renovatebot\u002Frenovate` | 2,456 | 154.5ms | 900.5ms |\n\nCounts reflect each fixture's generated benchmark config after excludes. Run\n`pnpm benchmark` to measure the same fixtures locally.\n\n## Config\n\nThe canonical config schema lives at root `codescythe.schema.json`. Bazel keeps\nthe crate-local `crates\u002Fcodescythe\u002Fcodescythe.schema.json` copy in sync with\n`write_source_file`, and that crate-local copy is compiled into the core crate.\nConfig can be provided as:\n\n- `codescythe.json` in the project root.\n- `codescythe.jsonc` in the project root, when `codescythe.json` is absent.\n- A `codescythe` object in `package.json`.\n- An explicit `.json` or `.jsonc` path passed with `--config`.\n\nSupported config fields are `entry`, `project`, `testFilePatterns`, `ignore`,\n`aliases`, `unresolvedImports`, `includeEntryExports`, and\n`ignoreExportsUsedInFile`. Codescythe automatically discovers `.gitignore` files\nin every traversed directory.\n\nFiles matching `testFilePatterns` are treated as leaf files. By default this\nincludes `**\u002F*.test.*`: those files are kept out of production usage marking,\nbut `--fix` can remove them when they import a project file or export that\nCodescythe is removing. When a matching test imports live production source, its\nproject-file imports are also kept out of the unused-file report. `.spec.*`\nfiles are not matched by default; model detached end-to-end specs as entries\ninstead.\n\nExports annotated with a leading JSDoc `@internal` tag are the exception to the\ntest leaf rule. If a matching test imports an `@internal` export, Codescythe\nkeeps that export and its reachable dependency graph. If the `@internal` export\nis not used by production code or tests, it is still reported as unused. Verbose\nanalysis and `--explain-export` show test importers that kept an internal export\nalive, and `codescythe doctor` lists internal exports preserved by tests.\nImporter and explain reasons are serialized as `{ code, description }` objects\nwith fixed `code` values so JSON consumers can branch on stable reason codes\ninstead of parsing display text.\n\nUse `--verbose --json` when validating config changes or comparing runs. Verbose\nanalysis includes the Codescythe version, config path, project and entry counts,\npackage import keys, ignored unresolved-import patterns, source-alias ignore\nwarnings, and explanations for unused exports. Ignored unresolved imports are\ngrouped under `ignoredUnresolvedImportsByPattern` with sample specifiers and\nimporter files, so generated-import suppressions are visible instead of being\nsilent.\n\nThe source graph includes static imports and re-exports, string-literal dynamic\nimports, destructured `require(\".\u002Fmodule\")` calls, and `import.meta.glob`\npatterns. `import.meta.glob` marks the matched project files and their exports\nas used; computed patterns and non-literal dynamic imports remain outside the\nsupported graph.\n\n## Fixing\n\nRun Codescythe with `--fix` to apply supported removals. The fix pass removes\nunused project files and removes unused export declarations from reachable files.\nThe JSON fix report includes `removedFiles`, `changedFiles`, `removedExports`,\nand the original analysis result.\n\n`--fix` refuses source-like unresolved-import ignore patterns that overlap\npackage `imports` or configured source aliases unless `--force` is provided.\nExtensionless and JS\u002FTS-family patterns can hide real source imports, while\nnon-JS\u002FTS asset patterns such as `*.svg?raw` still warn but do not block\n`--fix`. When ignored unresolved imports create alias-namespace uncertainty for\na file, Codescythe skips export edits for that file and reports it in\n`skippedExportFiles`.\n\nFixing is a single analysis-and-edit pass. Removing a dead file can make more\nfiles or exports unreachable, so repeated cleanup jobs should run Codescythe\nagain after a fix pass when a completely stable tree is required.\n\n## Explanations And Doctor\n\nUse `--explain-export \u003Cfile>:\u003Csymbol>` to ask why one export is dead or alive:\n\n```sh\ncodescythe --explain-export src\u002Fconstants.ts:getServerId\n```\n\nUse `doctor` to check config risk before running destructive fixes:\n\n```sh\ncodescythe doctor --config codescythe.jsonc\n```\n\nThe doctor flags broad unresolved-import ignores under local aliases, unresolved\nimports, entry patterns with zero matches, project scopes that appear much\nbroader than entry coverage, and generated ignore patterns that also match\nchecked source files. When unresolved imports are present, JSON doctor output\nincludes sampled resolver diagnostics with matched aliases, expanded targets,\ncandidate files, and whether each candidate exists in the project.\n\n## Querying Dependency Paths\n\nUse `query` to inspect dependency paths through the same source graph:\n\n```sh\ncodescythe query somepath src\u002Fmain.ts src\u002Fmodule.ts\ncodescythe query somepath src\u002Fmain.ts src\u002Ffeatures\u002F\ncodescythe query allpaths src\u002Fmain.ts src\u002Fruntime.ts:initRuntime --json\ncodescythe query allpaths src\u002Fmain.ts src\u002Fruntime.ts:initRuntime --output mermaid\ncodescythe query allpaths src\u002Fmain.ts src\u002Fruntime.ts:initRuntime --output svg > graph.svg\n```\n\nSelectors can point at files, directories, or exported symbols written as\n`\u003Cfile>:\u003Csymbol>`. Relative selectors are resolved from the analysis root chosen\nby `-C` or `--config`.\n\n- `somepath` returns one shortest path per reachable matched target. File and\n  export targets usually match one target, while directory targets can match\n  many.\n- `allpaths` returns the subgraph of every node and edge that lies on a path\n  from the source selector to the target selector.\n\nText output is optimized for terminal inspection. JSON output includes stable\nfile\u002Fexport nodes and typed import or re-export edges. Mermaid output renders\nthe same query graph as a `flowchart LR` diagram, and SVG output renders that\nMermaid source with the pure-Rust `mermaid-rs-renderer` crate.\n\n`somepath` uses breadth-first search with visited nodes, while `allpaths`\nintersects forward reachability from the source with reverse reachability from\nthe target. That makes dependency cycles finite without enumerating every\npossible walk through the graph.\n\nFixture-backed Mermaid examples:\n\n```sh\ncodescythe query somepath \\\n  -C tests\u002Ffixtures\u002Ftest-file-usage \\\n  --output mermaid \\\n  src\u002Fmain.ts \\\n  src\u002Fmodule.ts:used\n```\n\n```mermaid\nflowchart LR\n  n0[\"src\u002Fmodule.ts:used\"]\n  n1[\"src\u002Fmain.ts\"]\n  n1 -->|\"named import .\u002Fmodule:used\"| n0\n```\n\n```sh\ncodescythe query somepath \\\n  -C tests\u002Ffixtures\u002Foxc-resolution \\\n  --output mermaid \\\n  app\u002Findex.ts \\\n  app\u002F\n```\n\n```mermaid\nflowchart LR\n  n0[\"app\u002Faliased.ts:aliased\"]\n  n1[\"app\u002Fextension.ts:extension\"]\n  n2[\"app\u002Finternal.ts:internal\"]\n  n3[\"app\u002Faliased.ts\"]\n  n4[\"app\u002Fextension.ts\"]\n  n5[\"app\u002Findex.ts\"]\n  n6[\"app\u002Finternal.ts\"]\n  n0 -->|\"defined in file aliased\"| n3\n  n1 -->|\"defined in file extension\"| n4\n  n2 -->|\"defined in file internal\"| n6\n  n5 -->|\"named import @\u002Faliased:aliased\"| n0\n  n5 -->|\"named import .\u002Fextension.js:extension\"| n1\n  n5 -->|\"named import #internal:internal\"| n2\n```\n\n```sh\ncodescythe query allpaths \\\n  -C tests\u002Ffixtures\u002Fknip-export-basics \\\n  --output mermaid \\\n  index.ts \\\n  my-namespace.ts:y\n```\n\n```mermaid\nflowchart LR\n  n0[\"index.ts\"]\n  n1[\"my-module.ts\"]\n  n2[\"my-module.ts:myExport\"]\n  n3[\"my-namespace.ts:y\"]\n  n2 -->|\"defined in file myExport\"| n1\n  n0 -->|\"named import .\u002Fmy-module.js:myExport\"| n2\n  n1 -->|\"namespace member .\u002Fmy-namespace.js:y\"| n3\n```\n\n```sh\ncodescythe query somepath \\\n  -C tests\u002Ffixtures\u002Frunfiles-fixture \\\n  --output mermaid \\\n  workspace\u002Ffrontend\u002Fapps\u002Fclient\u002Fplatform\u002FplatformRuntime.ts \\\n  protobuf\u002Fgenerated\u002Fclient.ts:client\n```\n\n```mermaid\nflowchart LR\n  n0[\"protobuf\u002Fgenerated\u002Fclient.ts:client\"]\n  n1[\"workspace\u002Ffrontend\u002Fapps\u002Fclient\u002Fplatform\u002FplatformRuntime.ts\"]\n  n1 -->|\"named import #bazel_generated\u002Fclient:client\"| n0\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the repository layout, architecture,\nbuild graph, benchmarks, release artifacts, and local validation commands.\n","Codescythe 是一个专注于 TypeScript 和 JavaScript 的死代码分析与移除工具。它通过从已知入口点开始，追踪导入\u002F导出图谱，来识别项目中未使用的文件或导出符号。与同类工具相比，Codescythe 选择了一个更窄的范围，避免了广泛的框架集成层，使得分析更加易于理解和测试，并且可以作为自动化清理的一部分运行。该工具特别适合于那些边界明确、需要确定性答案（即哪些源文件和导出是未被使用的）的包和单体仓库维护场景。使用 Rust 编写，保证了高效性能，在多个实际项目中的基准测试中表现优异。",2,"2026-06-11 04:06:59","CREATED_QUERY"]