Unused Code Detection Tools


Jun 28, 2025

ACCEPTED

Development Team

#frontend #static #analysis #code #quality #dead #code

Context and Problem Statement

As our codebase grows, it becomes increasingly important to identify and remove unused code to maintain a clean, efficient, and maintainable codebase. Unused code, including unused exports, dependencies, and files, can lead to increased bundle size, maintenance overhead, and confusion for developers.

In our previous decision (Unused Code Detection Tools), we chose to use both knip and ts-prune. However, after further evaluation, we found that knip alone can handle all our unused code detection needs, allowing us to simplify our tooling.

Decision Drivers

  • Support for TypeScript
  • Ability to detect different types of unused code (exports, dependencies, files)
  • Integration with our build and CI processes
  • Developer experience and ease of use
  • Accuracy of detection
  • Customizability and configuration options
  • Minimal false positives
  • Tooling simplification and maintenance

Considered Options

  • Continue using both knip and ts-prune
  • Use only knip
  • Use only ts-prune

Decision Outcome

Chosen option: Use only knip

We have decided to use only knip for the Newgotiate UI application to provide comprehensive coverage of unused code detection.

Reasoning

  1. Comprehensive Coverage: knip provides broad detection capabilities for unused dependencies, files, exports, and more, making ts-prune redundant.

  2. TypeScript Support: knip has excellent support for TypeScript, which is our primary language.

  3. Simplified Tooling: Using a single tool reduces maintenance overhead and configuration complexity.

  4. Advanced Configuration: knip's configuration options allow us to ignore specific patterns and files, providing the same flexibility we had with ts-prune.

  5. Active Development: knip is actively maintained and has better community support.

Implementation Notes

  • Configuration for knip is stored in knip.json at the project root
  • We've updated our pre-commit hooks to use only knip via the lint:unused script
  • Custom ignore patterns have been established for generated code, storybook index files, and other specific files
  • The pre-commit process will fail if unused exports are detected

Consequences

  • Simplified tooling setup and maintenance
  • Consistent configuration in a single file
  • Reduced dependencies in our project
  • Developers only need to be familiar with one tool's configuration

Pros and Cons of the Options

Continue using both knip and ts-prune

  • Good, because it provides redundancy in detection
  • Good, because ts-prune is specifically optimized for TypeScript exports
  • Bad, because it requires maintaining two separate configurations
  • Bad, because it adds complexity to our tooling setup
  • Bad, because there is significant overlap in functionality

Use only knip

  • Good, because it provides comprehensive detection of unused dependencies, exports, and files
  • Good, because it has excellent TypeScript support
  • Good, because it integrates well with modern JavaScript/TypeScript projects
  • Good, because it has active community support and documentation
  • Good, because it simplifies our tooling setup with a single configuration
  • Bad, because it may produce some false positives that require configuration to ignore

Use only ts-prune

  • Good, because it focuses specifically on unused TypeScript exports with high precision
  • Good, because it has a simple, straightforward API
  • Good, because it's lightweight and fast
  • Bad, because it only detects unused exports, not other types of unused code
  • Bad, because it requires additional scripting for proper error handling in CI environments
  • Bad, because it lacks the comprehensive features of knip