{"id":48821536,"url":"https://github.com/nermalcat69/tsx-prune","last_synced_at":"2026-04-14T15:02:34.643Z","repository":{"id":343382437,"uuid":"1177473092","full_name":"nermalcat69/tsx-prune","owner":"nermalcat69","description":"tool to remove all unused components","archived":false,"fork":false,"pushed_at":"2026-03-10T04:46:32.000Z","size":100,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-10T12:18:02.106Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nermalcat69.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-10T03:55:48.000Z","updated_at":"2026-03-10T04:46:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nermalcat69/tsx-prune","commit_stats":null,"previous_names":["nermalcat69/tsx-prune"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/nermalcat69/tsx-prune","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nermalcat69%2Ftsx-prune","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nermalcat69%2Ftsx-prune/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nermalcat69%2Ftsx-prune/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nermalcat69%2Ftsx-prune/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nermalcat69","download_url":"https://codeload.github.com/nermalcat69/tsx-prune/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nermalcat69%2Ftsx-prune/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31801629,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T11:13:53.975Z","status":"ssl_error","status_checked_at":"2026-04-14T11:13:53.299Z","response_time":153,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-14T15:02:29.966Z","updated_at":"2026-04-14T15:02:34.637Z","avatar_url":"https://github.com/nermalcat69.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tsx-prune\n\n\u003e Analyze and safely remove unused components, files, imports, and exports in TypeScript/React codebases.\n\n[![npm version](https://img.shields.io/npm/v/tsx-prune.svg)](https://www.npmjs.com/package/tsx-prune)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n---\n\n## Features\n\n- **Unused file detection** — find files unreachable from your entry points\n- **Unused export detection** — find exports never imported anywhere\n- **Unused import detection** — find and remove imports not used in the file body\n- **React component detection** — detect JSX components never referenced anywhere\n- **Safe deletion** — never deletes test files, stories, or spec files\n- **Config file support** — `tsx-prune.config.ts` / `tsx-prune.config.json`\n- **tsconfig path aliases** — respects `baseUrl` and `paths` from your `tsconfig.json`\n- **JSON output** — machine-readable output for CI pipelines\n- **Fast** — uses ts-morph AST cache and fast-glob for 10k+ file projects\n\n---\n\n## Installation\n\n```bash\n# Global install\nbun add -g tsx-prune\nnpm install -g tsx-prune\n\n# Or use without installing\nbunx tsx-prune\nnpx tsx-prune\n```\n\n---\n\n## Usage\n\n```bash\n# Dry run (default) — shows what would be removed\ntsx-prune\n\n# Delete unused files\ntsx-prune --delete\n\n# Remove unused imports\ntsx-prune --fix-imports\n\n# Remove export modifier from unused exports\ntsx-prune --fix-exports\n\n# All fixes together\ntsx-prune --delete --fix-imports --fix-exports\n\n# Custom entry points\ntsx-prune --entry src/main.tsx src/server.ts\n\n# Ignore patterns\ntsx-prune --ignore \"src/legacy/**\" \"src/vendor/**\"\n\n# JSON output (for CI)\ntsx-prune --json\n\n# Silent mode\ntsx-prune --silent\n\n# Custom tsconfig\ntsx-prune --tsconfig tsconfig.app.json\n\n# Use a config file\ntsx-prune --config tsx-prune.config.ts\n```\n\n---\n\n## Example Output\n\n```\n  Scanning 342 files...\n  Entry points: 3 found\n\n  Unused Files:\n    ✗ src/components/OldCard.tsx\n    ✗ src/utils/legacyHelpers.ts\n    2 unused files found\n\n  Unused Exports:\n    src/components/Button.tsx\n      ✗ \u003cButtonGroup\u003e\n      ✗ ButtonSize\n\n    1 file with unused exports\n\n  Unused React Components:\n    \u003cButtonGroup\u003e, \u003cCardVariant\u003e\n    2 unused components found\n\n  ─────────────────────────────────────────\n  Summary: 342 files scanned\n    ✗ 2 unused files\n    ✗ 2 unused exports\n    ✗ 2 unused React components\n\n  Dry run complete. Use --delete to remove files.\n```\n\n---\n\n## Configuration File\n\nCreate `tsx-prune.config.ts` (or `.json`) at your project root:\n\n```ts\n// tsx-prune.config.ts\nexport default {\n  entry: [\"src/main.tsx\", \"src/server.ts\"],\n  ignore: [\n    \"src/legacy/**\",\n    \"src/vendor/**\",\n    \"**/*.generated.ts\",\n  ],\n};\n```\n\n```json\n// tsx-prune.config.json\n{\n  \"entry\": [\"src/main.tsx\"],\n  \"ignore\": [\"src/legacy/**\"]\n}\n```\n\n---\n\n## Options\n\n| Flag | Description | Default |\n|------|-------------|---------|\n| `--delete` | Delete unused files | `false` (dry run) |\n| `--dry-run` | Show what would be deleted | `true` |\n| `--fix-imports` | Remove unused import statements | `false` |\n| `--fix-exports` | Remove `export` from unused exports | `false` |\n| `--entry \u003cpaths...\u003e` | Entry point files or globs | `src/main.tsx`, `src/index.tsx`, etc. |\n| `--ignore \u003cpatterns...\u003e` | Additional glob patterns to ignore | — |\n| `--root \u003cdir\u003e` | Root directory to scan | `process.cwd()` |\n| `--tsconfig \u003cpath\u003e` | Path to tsconfig.json | `./tsconfig.json` |\n| `--json` | Output results as JSON | `false` |\n| `--silent` | Suppress all output | `false` |\n| `--config \u003cpath\u003e` | Path to config file | auto-detected |\n\n---\n\n## Default Entry Points\n\nWhen no `--entry` is specified, tsx-prune looks for:\n\n- `src/main.tsx` / `src/main.ts`\n- `src/index.tsx` / `src/index.ts`\n- `src/app.tsx` / `src/App.tsx`\n- `src/pages/**` (Next.js pages router)\n- `src/app/**` (Next.js app router)\n- `pages/**`\n- `app/**`\n\n---\n\n## Safety Rules\n\ntsx-prune **never** deletes:\n\n- `*.test.ts` / `*.test.tsx`\n- `*.spec.ts` / `*.spec.tsx`\n- `*.stories.tsx` / `*.stories.ts`\n- Files inside `__tests__/` or `tests/`\n- Files inside `.storybook/`\n- Files with dynamic imports pointing to them\n\n---\n\n## Comparison\n\n| Feature | tsx-prune | ts-prune | knip |\n|---------|-----------|----------|------|\n| Unused files | ✓ | — | ✓ |\n| Unused exports | ✓ | ✓ | ✓ |\n| Unused imports | ✓ | — | ✓ |\n| React component detection | ✓ | — | — |\n| Safe deletion CLI | ✓ | — | — |\n| JSX-aware analysis | ✓ | — | — |\n| tsconfig paths | ✓ | — | ✓ |\n| Config file | ✓ | — | ✓ |\n| JSON output | ✓ | — | ✓ |\n| React-optimized | ✓ | — | — |\n\n---\n\n## Programmatic API\n\n```ts\nimport {\n  scanFiles,\n  Parser,\n  buildGraphFromFileInfos,\n  analyze,\n  reportAnalysis,\n} from \"tsx-prune\";\n\nconst files = await scanFiles({\n  root: \"./src\",\n  extensions: [\".ts\", \".tsx\"],\n  ignore: [],\n  entry: [],\n});\n\nconst parser = new Parser({\n  tsconfig: \"./tsconfig.json\",\n  root: \"./src\",\n  extensions: [\".ts\", \".tsx\"],\n});\n\nparser.addFiles(files);\nconst fileInfos = new Map(files.map((f) =\u003e [f, parser.parseFile(f)]));\n\nconst graph = buildGraphFromFileInfos(fileInfos);\nconst result = analyze(graph, fileInfos, {\n  entryPoints: [\"./src/main.tsx\"],\n  ignorePatterns: [],\n});\n\nreportAnalysis(result, { json: false, silent: false, cwd: process.cwd() });\n```\n\n---\n\n## Development\n\n```bash\n# Install dependencies\nbun install\n\n# Build\nbun run build\n\n# Run directly (no build step needed with Bun)\nbun run src/cli.ts\n\n# Type-check\nbun run lint\n\n# Test\nbun test\n```\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnermalcat69%2Ftsx-prune","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnermalcat69%2Ftsx-prune","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnermalcat69%2Ftsx-prune/lists"}