Skip to content

Unused Code Detection Tools

  • Status: accepted
  • Deciders: Development Team
  • Date: 2025-06-27
  • Tags: 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 (20250626-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