Clean Up Your Codebase with Knip - Find Dead Code in Seconds

3 min read
TypeScriptJavaScriptDevelopmentCode QualityDead Code
Abhay Ramesh
Abhay Ramesh
Full Stack Developer

TL;DR - Find unused code in your project
Run this in your terminal:

npx knip

The Problem

As codebases grow, it's common to accumulate:

  • Unused exports and types
  • Dead files that no one uses anymore
  • Dependencies listed in package.json but never imported
  • Duplicate or obsolete code paths

Manually finding these is time-consuming and error-prone.

The Solution

Knip is a powerful tool that finds unused:

  • Exports (functions, types, components)
  • Files
  • Dependencies
  • Package.json entries

Add it to your project:

npm install -D knip
# or
yarn add -D knip
# or
pnpm add -D knip

Add to your package.json:

{
  "scripts": {
    "knip": "knip"
  }
}

What It Finds

  1. Unused Exports:

    // Only Component1 is used elsewhere
    export const Component1 = () => <div>Used</div>;
    export const Component2 = () => <div>Never imported!</div>; // Knip will find this
  2. Dead Files:

    // oldUtils.ts - no imports anywhere
    export const formatDate = (date: Date) => {
      // This entire file is unused
    };
  3. Unused Dependencies:

    {
      "dependencies": {
        "used-package": "^1.0.0",
        "never-imported": "^2.0.0" // Knip will flag this
      }
    }

Configuration

Create knip.json for custom configuration:

{
  "entry": ["src/index.ts", "src/pages/**/*.tsx"],
  "project": ["src/**/*.{ts,tsx}"],
  "ignore": ["**/*.test.ts"],
  "ignoreDependencies": ["typescript"]
}

Real-World Example

Let's say you have a React component library:

// components/index.ts
export * from "./Button";
export * from "./Input";
export * from "./Card";
export * from "./OldComponent"; // No one uses this anymore
 
// components/OldComponent.tsx
export const OldComponent = () => {
  return <div>I'm never used!</div>;
};

Running knip will show:

unused-export components/index.ts:4 - export from './OldComponent'
unused-file components/OldComponent.tsx - file is never imported

Pro Tips

  1. CI Integration:

    - name: Check Dead Code
      run: npx knip --strict
  2. Git Hooks:

    {
      "husky": {
        "hooks": {
          "pre-push": "npm run knip"
        }
      }
    }
  3. With Reporter:

    {
      "scripts": {
        "knip:report": "knip --reporter json > deadcode-report.json"
      }
    }

Benefits

  1. Smaller Bundle Size: Remove unused code
  2. Better Maintainability: Less code to maintain
  3. Cleaner Dependencies: Only keep what you use
  4. Improved Performance: Less code to parse and compile
  5. Better Developer Experience: Clear understanding of what code is actually used

Common Use Cases

  1. Before Major Refactoring:

    # Check current state
    npm run knip
    # Remove flagged code
    # Run again to verify
    npm run knip
  2. Cleaning Dependencies:

    # Find unused packages
    npx knip --dependencies
    # Remove them
    npm remove [unused-package]
  3. Continuous Monitoring:

    {
      "scripts": {
        "knip:watch": "knip --watch"
      }
    }

Best Practices

  1. Start Clean:

    • Run on new projects early
    • Easier to maintain than clean up later
  2. Regular Checks:

    • Run before major releases
    • Part of code review process
  3. Incremental Adoption:

    {
      "scripts": {
        "knip:strict": "knip --strict",
        "knip:warn": "knip --reporter warning"
      }
    }

Note: While Knip is great at finding unused code, always verify its suggestions before deletion. Some code might be used dynamically or through reflection.