https://github.com/nermalcat69/tsx-prune
tool to remove all unused components
https://github.com/nermalcat69/tsx-prune
Last synced: 2 months ago
JSON representation
tool to remove all unused components
- Host: GitHub
- URL: https://github.com/nermalcat69/tsx-prune
- Owner: nermalcat69
- License: mit
- Created: 2026-03-10T03:55:48.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-03-10T04:46:32.000Z (3 months ago)
- Last Synced: 2026-03-10T12:18:02.106Z (3 months ago)
- Language: TypeScript
- Size: 97.7 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# tsx-prune
> Analyze and safely remove unused components, files, imports, and exports in TypeScript/React codebases.
[](https://www.npmjs.com/package/tsx-prune)
[](https://opensource.org/licenses/MIT)
---
## Features
- **Unused file detection** — find files unreachable from your entry points
- **Unused export detection** — find exports never imported anywhere
- **Unused import detection** — find and remove imports not used in the file body
- **React component detection** — detect JSX components never referenced anywhere
- **Safe deletion** — never deletes test files, stories, or spec files
- **Config file support** — `tsx-prune.config.ts` / `tsx-prune.config.json`
- **tsconfig path aliases** — respects `baseUrl` and `paths` from your `tsconfig.json`
- **JSON output** — machine-readable output for CI pipelines
- **Fast** — uses ts-morph AST cache and fast-glob for 10k+ file projects
---
## Installation
```bash
# Global install
bun add -g tsx-prune
npm install -g tsx-prune
# Or use without installing
bunx tsx-prune
npx tsx-prune
```
---
## Usage
```bash
# Dry run (default) — shows what would be removed
tsx-prune
# Delete unused files
tsx-prune --delete
# Remove unused imports
tsx-prune --fix-imports
# Remove export modifier from unused exports
tsx-prune --fix-exports
# All fixes together
tsx-prune --delete --fix-imports --fix-exports
# Custom entry points
tsx-prune --entry src/main.tsx src/server.ts
# Ignore patterns
tsx-prune --ignore "src/legacy/**" "src/vendor/**"
# JSON output (for CI)
tsx-prune --json
# Silent mode
tsx-prune --silent
# Custom tsconfig
tsx-prune --tsconfig tsconfig.app.json
# Use a config file
tsx-prune --config tsx-prune.config.ts
```
---
## Example Output
```
Scanning 342 files...
Entry points: 3 found
Unused Files:
✗ src/components/OldCard.tsx
✗ src/utils/legacyHelpers.ts
2 unused files found
Unused Exports:
src/components/Button.tsx
✗
✗ ButtonSize
1 file with unused exports
Unused React Components:
,
2 unused components found
─────────────────────────────────────────
Summary: 342 files scanned
✗ 2 unused files
✗ 2 unused exports
✗ 2 unused React components
Dry run complete. Use --delete to remove files.
```
---
## Configuration File
Create `tsx-prune.config.ts` (or `.json`) at your project root:
```ts
// tsx-prune.config.ts
export default {
entry: ["src/main.tsx", "src/server.ts"],
ignore: [
"src/legacy/**",
"src/vendor/**",
"**/*.generated.ts",
],
};
```
```json
// tsx-prune.config.json
{
"entry": ["src/main.tsx"],
"ignore": ["src/legacy/**"]
}
```
---
## Options
| Flag | Description | Default |
|------|-------------|---------|
| `--delete` | Delete unused files | `false` (dry run) |
| `--dry-run` | Show what would be deleted | `true` |
| `--fix-imports` | Remove unused import statements | `false` |
| `--fix-exports` | Remove `export` from unused exports | `false` |
| `--entry ` | Entry point files or globs | `src/main.tsx`, `src/index.tsx`, etc. |
| `--ignore ` | Additional glob patterns to ignore | — |
| `--root ` | Root directory to scan | `process.cwd()` |
| `--tsconfig ` | Path to tsconfig.json | `./tsconfig.json` |
| `--json` | Output results as JSON | `false` |
| `--silent` | Suppress all output | `false` |
| `--config ` | Path to config file | auto-detected |
---
## Default Entry Points
When no `--entry` is specified, tsx-prune looks for:
- `src/main.tsx` / `src/main.ts`
- `src/index.tsx` / `src/index.ts`
- `src/app.tsx` / `src/App.tsx`
- `src/pages/**` (Next.js pages router)
- `src/app/**` (Next.js app router)
- `pages/**`
- `app/**`
---
## Safety Rules
tsx-prune **never** deletes:
- `*.test.ts` / `*.test.tsx`
- `*.spec.ts` / `*.spec.tsx`
- `*.stories.tsx` / `*.stories.ts`
- Files inside `__tests__/` or `tests/`
- Files inside `.storybook/`
- Files with dynamic imports pointing to them
---
## Comparison
| Feature | tsx-prune | ts-prune | knip |
|---------|-----------|----------|------|
| Unused files | ✓ | — | ✓ |
| Unused exports | ✓ | ✓ | ✓ |
| Unused imports | ✓ | — | ✓ |
| React component detection | ✓ | — | — |
| Safe deletion CLI | ✓ | — | — |
| JSX-aware analysis | ✓ | — | — |
| tsconfig paths | ✓ | — | ✓ |
| Config file | ✓ | — | ✓ |
| JSON output | ✓ | — | ✓ |
| React-optimized | ✓ | — | — |
---
## Programmatic API
```ts
import {
scanFiles,
Parser,
buildGraphFromFileInfos,
analyze,
reportAnalysis,
} from "tsx-prune";
const files = await scanFiles({
root: "./src",
extensions: [".ts", ".tsx"],
ignore: [],
entry: [],
});
const parser = new Parser({
tsconfig: "./tsconfig.json",
root: "./src",
extensions: [".ts", ".tsx"],
});
parser.addFiles(files);
const fileInfos = new Map(files.map((f) => [f, parser.parseFile(f)]));
const graph = buildGraphFromFileInfos(fileInfos);
const result = analyze(graph, fileInfos, {
entryPoints: ["./src/main.tsx"],
ignorePatterns: [],
});
reportAnalysis(result, { json: false, silent: false, cwd: process.cwd() });
```
---
## Development
```bash
# Install dependencies
bun install
# Build
bun run build
# Run directly (no build step needed with Bun)
bun run src/cli.ts
# Type-check
bun run lint
# Test
bun test
```
---
## License
MIT