knip dead code detection

Knip Dead Code Detection

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "knip dead code detection" with this command: npx skills add laurigates/claude-plugins/laurigates-claude-plugins-knip-dead-code-detection

Knip Dead Code Detection

Knip is a comprehensive tool for finding unused code, dependencies, and exports in JavaScript and TypeScript projects. It helps maintain clean codebases and catch dead code before it accumulates.

Core Expertise

What is Knip?

  • Unused detection: Files, dependencies, exports, types, enum members

  • Plugin system: Supports 80+ frameworks and tools

  • Fast: Analyzes large codebases in seconds

  • Actionable: Clear reports with file locations

  • CI-ready: Exit codes for failing builds

Key Capabilities

  • Detect unused dependencies (npm, workspace packages)

  • Find unused exports and types

  • Identify unused files

  • Discover unused enum members and class members

  • Detect re-exports that aren't used

  • Plugin support for frameworks (React, Next.js, Vue, Svelte)

  • Integration with monorepos and workspaces

Installation

Project-local (recommended)

bun add --dev knip

Global installation

bun add --global knip

Verify installation

bunx knip --version

Basic Usage

Run Knip (scans entire project)

bunx knip

Show only unused dependencies

bunx knip --dependencies

Show only unused exports

bunx knip --exports

Show only unused files

bunx knip --files

Production mode (only check production dependencies)

bunx knip --production

Exclude specific issue types

bunx knip --exclude-exports-used-in-file

Output JSON (for CI)

bunx knip --reporter json

Debug mode (show configuration)

bunx knip --debug

Configuration

Auto-detection (Zero Config)

Knip automatically detects:

  • Entry points (package.json main , exports , bin )

  • Frameworks (Next.js, Vite, Remix, etc.)

  • Test runners (Vitest, Jest, Playwright)

  • Build tools (ESLint, TypeScript, PostCSS)

No configuration needed for standard projects.

knip.json (Explicit Configuration)

{ "$schema": "https://unpkg.com/knip@latest/schema.json", "entry": ["src/index.ts", "src/cli.ts"], "project": ["src//*.ts"], "ignore": ["/.test.ts", "scripts/**"], "ignoreDependencies": ["@types/"], "ignoreBinaries": ["npm-check-updates"] }

knip.ts (TypeScript Configuration)

// knip.ts import type { KnipConfig } from 'knip';

const config: KnipConfig = { entry: ['src/index.ts', 'src/cli.ts'], project: ['src//*.ts', 'scripts//.ts'], ignore: ['**/.test.ts', '/*.spec.ts', 'tmp/'], ignoreDependencies: [ '@types/*', // Type definitions 'typescript', // Always needed ], ignoreExportsUsedInFile: true, ignoreWorkspaces: ['packages/legacy/**'], };

export default config;

Recommended Production Setup

// knip.ts import type { KnipConfig } from 'knip';

const config: KnipConfig = { // Entry points entry: [ 'src/index.ts', 'src/cli.ts', 'scripts/**/*.ts', // Include scripts ],

// Project files project: ['src//*.{ts,tsx}', 'scripts//*.ts'],

// Ignore patterns ignore: [ '/*.test.ts', '/*.spec.ts', '/tests/', '/mocks/', 'dist/', 'build/', 'coverage/', '.next/', ],

// Dependencies to ignore ignoreDependencies: [ '@types/*', // Type definitions used implicitly 'typescript', // Always needed for TS projects 'tslib', // TypeScript helper library '@biomejs/biome', // Used via CLI 'prettier', // Used via CLI ],

// Binaries to ignore (used in package.json scripts) ignoreBinaries: ['npm-check-updates', 'semantic-release'],

// Ignore exports used in the same file ignoreExportsUsedInFile: true,

// Workspace configuration (for monorepos) workspaces: { '.': { entry: ['src/index.ts'], }, 'packages/*': { entry: ['src/index.ts', 'src/cli.ts'], }, }, };

export default config;

Plugin System

Knip automatically detects and configures plugins for popular tools:

Framework Plugins

Framework Auto-detected Entry Points

Next.js next.config.js

pages/ , app/ , middleware.ts

Vite vite.config.ts

index.html , config plugins

Remix remix.config.js

app/root.tsx , app/entry.*

Astro astro.config.mjs

src/pages/ , config integrations

SvelteKit svelte.config.js

src/routes/ , src/app.html

Nuxt nuxt.config.ts

app.vue , pages/ , layouts/

Test Runner Plugins

Tool Auto-detected Entry Points

Vitest vitest.config.ts

**/*.test.ts , config files

Jest jest.config.js

**/*.test.js , setup files

Playwright playwright.config.ts

tests/**/*.spec.ts

Cypress cypress.config.ts

cypress/e2e/**/*.cy.ts

Build Tool Plugins

Tool Auto-detected Entry Points

TypeScript tsconfig.json

Files in include

ESLint .eslintrc.js

Config files, plugins

PostCSS postcss.config.js

Config plugins

Tailwind tailwind.config.js

Config plugins, content files

Plugin Configuration Override

// knip.ts const config: KnipConfig = { // Disable specific plugins eslint: false, prettier: false,

// Override plugin config vitest: { entry: ['vitest.config.ts', 'test/setup.ts'], config: ['vitest.config.ts'], },

next: { entry: [ 'next.config.js', 'pages//*.tsx', 'app//*.tsx', 'middleware.ts', 'instrumentation.ts', ], }, };

Ignoring Issues

Ignore Patterns

// knip.ts const config: KnipConfig = { // Ignore entire directories ignore: ['legacy/', 'vendor/'],

// Ignore specific dependencies ignoreDependencies: [ '@types/*', 'some-peer-dependency', ],

// Ignore specific exports ignoreExportsUsedInFile: { interface: true, // Ignore interfaces used only in same file type: true, // Ignore types used only in same file },

// Ignore workspace packages ignoreWorkspaces: ['packages/deprecated/**'], };

Inline Comments

// Ignore unused export // @knip-ignore-export export const unusedFunction = () => {};

// Ignore unused dependency in package.json { "dependencies": { "some-package": "1.0.0" // @knip-ignore-dependency } }

Whitelist Pattern

// knip.ts - Whitelist specific exports const config: KnipConfig = { entry: ['src/index.ts'], project: ['src/**/*.ts'],

// Only these exports are allowed to be unused (public API) exports: { include: ['src/index.ts'], }, };

CI/CD Integration

GitHub Actions

name: Knip on: push: branches: [main] pull_request:

jobs: knip: name: Check for unused code runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - uses: oven-sh/setup-bun@v2
    with:
      bun-version: latest

  - name: Install dependencies
    run: bun install --frozen-lockfile

  - name: Run Knip
    run: bunx knip --production

  - name: Run Knip (strict)
    run: bunx knip --max-issues 0

GitLab CI

knip: image: oven/bun:latest stage: test script: - bun install --frozen-lockfile - bunx knip --production only: - merge_requests - main

Pre-commit Hook

.pre-commit-config.yaml

repos:

  • repo: local hooks:
    • id: knip name: Knip entry: bunx knip language: system pass_filenames: false

Common Patterns

Check Only Unused Dependencies

Fastest check - only dependencies

bunx knip --dependencies

Exit with error if any unused dependencies

bunx knip --dependencies --max-issues 0

Use in CI to enforce strict dependency hygiene.

Check Only Exports (Library Development)

Check for unused exports

bunx knip --exports

Allow exports used in same file

bunx knip --exports --exclude-exports-used-in-file

Use for libraries to ensure clean public API.

Production vs Development Dependencies

Check production code only

bunx knip --production

Check everything (including dev dependencies)

bunx knip

Monorepo Workflows

// knip.ts const config: KnipConfig = { workspaces: { '.': { entry: ['scripts/**/*.ts'], ignoreDependencies: ['@org/internal-package'], }, 'packages/web': { entry: ['src/index.ts', 'src/App.tsx'], ignoreDependencies: ['react', 'react-dom'], // Provided by parent }, 'packages/api': { entry: ['src/server.ts'], }, }, };

Check all workspaces

bunx knip

Check specific workspace

bunx knip --workspace packages/web

Interpreting Results

Example Output

✓ No unused files ✓ No unused dependencies ✗ 2 unused exports

src/utils.ts:

  • calculateTax (line 42)
  • formatDate (line 58)

src/types.ts:

  • UserRole (line 12)

Issue Types

Type Description Action

Unused file File not imported anywhere Delete or add to entry points

Unused dependency Package in package.json not used Remove from dependencies

Unused export Exported but never imported Remove export or make private

Unused type Type/interface exported but unused Remove or make internal

Unused enum member Enum member never referenced Remove member

Duplicate export Same export from multiple files Consolidate exports

Troubleshooting

False Positives (Exports Used via Side Effects)

// knip.ts const config: KnipConfig = { // Ignore exports that are used via side effects ignoreExportsUsedInFile: true,

// Or add to entry points entry: ['src/index.ts', 'src/side-effect-file.ts'], };

Knip Not Finding Entry Points

Debug configuration

bunx knip --debug

Manually specify entry points

bunx knip --entry src/index.ts --entry src/cli.ts

Performance Issues

Exclude node_modules explicitly (usually automatic)

bunx knip --exclude '/node_modules/'

Use .gitignore patterns

bunx knip --include-libs false

Increase memory limit

NODE_OPTIONS=--max-old-space-size=4096 bunx knip

Plugin Not Detected

// knip.ts - Force enable plugin const config: KnipConfig = { vite: { entry: ['vite.config.ts'], config: ['vite.config.ts'], }, };

Unused Dependencies in Scripts

// package.json - Knip detects binaries in scripts { "scripts": { "lint": "eslint .", // Detects eslint dependency "test": "vitest" // Detects vitest dependency } }

If not detected:

// knip.ts const config: KnipConfig = { ignoreDependencies: ['eslint', 'vitest'], };

Advanced Usage

Custom Reporters

JSON output (for CI)

bunx knip --reporter json > knip-report.json

Compact output

bunx knip --reporter compact

Custom format (coming soon)

bunx knip --reporter custom

Incremental Checks (Changed Files Only)

Check only changed files (requires git)

bunx knip --changed

Since specific commit

bunx knip --changed --base main

Type Checking Integration

// knip.ts const config: KnipConfig = { // Include type-only imports as used includeTypeImports: true,

// Check for unused TypeScript types types: true, };

Best Practices

Start with Dependencies Only

Easiest wins first

bunx knip --dependencies

Then move to exports

bunx knip --exports

Finally check files

bunx knip --files

Gradual Adoption

// knip.ts - Start strict, then relax const config: KnipConfig = { // Start with critical paths only entry: ['src/index.ts'], project: ['src/core/**/*.ts'],

// Expand coverage over time // entry: ['src//*.ts'], // project: ['src//*.ts'], };

CI Strategy

Check dependencies in CI (fast, high value)

  • name: Check unused dependencies run: bunx knip --dependencies --max-issues 0

Check exports in PR (prevents API bloat)

  • name: Check unused exports run: bunx knip --exports if: github.event_name == 'pull_request'

Maintenance Schedule

  • Weekly: Run full Knip scan, clean up issues

  • PR Review: Check for new unused exports

  • Pre-release: Full scan with --production

  • Refactors: Run Knip before and after

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

python-code-quality

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-testing

No summary provided by upstream source.

Repository SourceNeeds Review