An open API service indexing awesome lists of open source software.

https://github.com/nadeesha/ts-prune

Find unused exports in a typescript project. ๐Ÿ›€
https://github.com/nadeesha/ts-prune

typescript utility

Last synced: 16 days ago
JSON representation

Find unused exports in a typescript project. ๐Ÿ›€

Awesome Lists containing this project

README

          

# ts-prune

[![npm](https://img.shields.io/npm/v/ts-prune)](https://www.npmjs.com/package/ts-prune) [![npm](https://img.shields.io/npm/dm/ts-prune)](https://www.npmjs.com/package/ts-prune) [![GitHub issues](https://img.shields.io/github/issues/nadeesha/ts-prune)](https://github.com/nadeesha/ts-prune/issues)

**Find potentially unused exports in your TypeScript project with zero configuration.**

## ๐Ÿ“ข Maintenance Notice

> **ts-prune is now in maintenance mode** - For new projects, we recommend [knip](https://github.com/webpro/knip) which carries forward the same mission with more features.

ts-prune will continue to receive:
- โœ… Critical bug fixes
- โœ… Security updates
- โœ… Dependency maintenance

We will **not** be adding new features or accepting feature PRs. The tool remains stable and production-ready for existing users.

## What is ts-prune?

ts-prune is a simple, fast tool that finds exported TypeScript/JavaScript code that isn't being used anywhere in your project. It helps you:

- ๐Ÿงน **Clean up dead code** - Remove exports that serve no purpose
- ๐Ÿ“ฆ **Reduce bundle size** - Eliminate unused code from your builds
- ๐Ÿ” **Improve code quality** - Keep your codebase lean and maintainable
- โšก **Zero configuration** - Works out of the box with any TypeScript project

## Quick Start

### Installation

```bash
# npm
npm install --save-dev ts-prune

# yarn
yarn add --dev ts-prune

# pnpm
pnpm add --save-dev ts-prune
```

### Basic Usage

```bash
# Run in your project root
npx ts-prune
```

**Example output:**
```
src/components/Button.ts:15 - ButtonVariant
src/utils/helpers.ts:8 - formatCurrency
src/types/user.ts:12 - UserRole
src/api/client.ts:45 - ApiResponse
```

Each line shows: `file:line - exportName`

## Examples

### Example 1: Finding Unused Exports

Given these files:

```typescript
// src/utils/math.ts
export const add = (a: number, b: number) => a + b;
export const subtract = (a: number, b: number) => a - b; // unused
export const multiply = (a: number, b: number) => a * b; // unused

// src/app.ts
import { add } from './utils/math';
console.log(add(2, 3));
```

Running `ts-prune` outputs:
```
src/utils/math.ts:2 - subtract
src/utils/math.ts:3 - multiply
```

### Example 2: Ignoring Specific Exports

Use `// ts-prune-ignore-next` to ignore specific exports:

```typescript
// src/api/types.ts
export interface User {
id: string;
name: string;
}

// ts-prune-ignore-next
export interface AdminUser extends User { // ignored by ts-prune
permissions: string[];
}

export interface Customer { // will be flagged if unused
customerId: string;
}
```

### Example 3: Working with Different File Types

ts-prune works with various TypeScript patterns:

```typescript
// Default exports
export default class MyClass {}

// Named exports
export const myFunction = () => {};
export type MyType = string;
export interface MyInterface {}

// Re-exports
export { SomethingElse } from './other-file';
export * from './barrel-file';
```

## Configuration

### CLI Options

```bash
ts-prune [options]
```

| Option | Description | Example |
|--------|-------------|---------|
| `-p, --project` | Path to tsconfig.json | `ts-prune -p tsconfig.build.json` |
| `-i, --ignore` | Ignore pattern (RegExp) | `ts-prune -i "test\|spec"` |
| `-s, --skip` | Skip files pattern | `ts-prune -s "\.test\.ts$"` |
| `-e, --error` | Exit with error code if unused exports found | `ts-prune -e` |
| `-u, --unusedInModule` | Skip exports marked as "used in module" | `ts-prune -u` |

### Configuration File

Create `.ts-prunerc` (JSON), `.ts-prunerc.js`, or add to `package.json`:

```json
{
"ignore": "components/(Button|Input)",
"skip": "\\.test\\.|test/",
"project": "tsconfig.build.json"
}
```

## Common Use Cases

### 1. CI/CD Integration

Add to your package.json:
```json
{
"scripts": {
"deadcode": "ts-prune",
"deadcode:ci": "ts-prune --error"
}
}
```

### 2. Pre-commit Hook

```json
{
"husky": {
"hooks": {
"pre-commit": "ts-prune --error"
}
}
}
```

### 3. Count Unused Exports

```bash
ts-prune | wc -l
```

### 4. Filter Results

```bash
# Ignore test files
ts-prune | grep -v "\.test\."

# Only show specific directories
ts-prune | grep "src/components"

# Ignore multiple patterns
ts-prune | grep -v -E "(test|spec|stories)"
```

## Understanding the Output

ts-prune categorizes exports into different types:

- **Regular unused export**: `src/file.ts:10 - exportName`
- **Used in module**: `src/file.ts:5 - localHelper (used in module)`
- Export is only used within the same file
- Use `-u` flag to ignore these

## Limitations

- **Dynamic imports**: `import('./dynamic-file')` usage might not be detected
- **String-based imports**: `require('module-name')` patterns
- **Framework magic**: Some frameworks use exports through reflection
- **Configuration files**: Exports in config files might appear unused

For these cases, use `// ts-prune-ignore-next` or configure ignore patterns.

## FAQ

### How accurate is ts-prune?

ts-prune is conservative and may show false positives for:
- Dynamically imported modules
- Framework-specific patterns (Angular services, React lazy loading)
- Build tool configurations

### Can I use this with JavaScript?

Yes! ts-prune works with `.js` files in TypeScript projects. Ensure your `tsconfig.json` includes JavaScript files:

```json
{
"compilerOptions": {
"allowJs": true
}
}
```

## Acknowledgements

Built with the excellent [ts-morph](https://github.com/dsherret/ts-morph) library and inspired by [this approach](https://gist.github.com/dsherret/0bae87310ce24866ae22425af80a9864) by [@dsherret](https://github.com/dsherret).

## Contributors



Nadeesha


Nadeesha Cabral




Snyk


Snyk bot




Dan


Dan Vanderkam




Josh


Josh Goldberg โœจ




Vitaly


Vitaly Iegorov




Simon


Simon Jang



The


The Gitter Badger




Tim


Tim Bodeit




Tim


Tim Saunders




Torkel


Torkel Rogstad




Victor


Victor Nogueira




William


William Candillon



curtvict/


curtvict




phiresky/


phiresky




Reece


Reece Daniels




Mikhail


Mikhail Belyaev




Jacob


Jacob Bandes-Storch




Ivo


Ivo Raisr



Hugo


Hugo Duprat




Davis


Davis Ford




David


David Graham




Caleb


Caleb Peterson




Ashok


Ashok Argent-Katwala




Amir


Amir Arad