Skip to content

Configuring Project Files

The entry and project file patterns are the first and most important options. Getting those right is essential to help you delete more code and make Knip faster:

  • Start with defaults. Only add targeted entry overrides when needed.
  • Use project patterns (with negations) to define the scope for Knip.
  • Use production mode to exclude tests and other non-production files.
  • Use ignore only to suppress issues in specific files; it does not exclude files from analysis.

Let’s dive in and expand on all of these.

Avoid adding too many files as entry files:

  1. Knip does not report unused exports in entry files by default.
  2. Proper entry and project patterns allow Knip to find unused files and exports.

Files are reported as unused if they are in the set of project files, but are not resolved from the entry files:

unused files = project files - (entry files + resolved files)

See entry files to see where Knip looks for entry files. Fine-tune entry and adjust project to fit your codebase.

When there are too many files in the analysis, start here.

For instance, routes are entry files except those prefixed with an underscore:

{
"entry": ["src/routes/*.ts", "!src/routes/_*.ts"]
}

Some files are not part of your source and are reported as unused (false positives)? Use negated project patterns:

{
"entry": ["src/index.ts"],
"project": ["src/**/*.ts", "!src/exclude/**"]
}

❌   Don’t use ignore for generated artifacts:

knip.json
{
"entry": ["src/index.ts", "scripts/*.ts"],
"ignore": ["build/**", "dist/**", "src/generated.ts"]
}

✅   Do define your project boundaries:

knip.json
{
"entry": ["src/index.ts", "scripts/*.ts"],
"project": ["src/**", "scripts/**"],
"ignore": ["src/generated.ts"]
}

Why this is better:

  • project defines what belongs to the codebase, so build outputs are excluded from analysis and unused file detection
  • ignore is for the few files that should be analyzed but contain exceptions
  • Improves performance by analyzing fewer files

Use ignore when a specific analyzed file is not handled properly by Knip or intentionally contains unused exports (e.g. generated files exporting “everything”):

{
"entry": ["src/index.ts"],
"project": ["src/**/*.ts"],
"ignore": ["src/generated.ts"]
}

Also see ignoreExportsUsedInFile for a more targeted approach.

Default mode includes tests and other non-production files in the analysis. To focus on production code, use production mode.

Don’t try to exclude tests via ignore or negated project patterns. That’s inefficient and ineffective due to entries added by plugins. Use production mode instead.

❌   Don’t do this:

{
"ignore": ["**/*.test.js"]
}

Why not: ignore hides issues from the report; it does not exclude files from analysis.

❌   Also don’t do this:

{
"entry": ["index.ts", "!**/*.test.js"]
}

Why not: plugins add test files as entry files; you can’t and shouldn’t override that globally.

❌   Or this:

{
"project": ["**/*.ts", "!**/*.spec.ts"]
}

Why not: project is for unused file detection; negating test files is ineffective because they are entry files.

✅   Do this instead:

Terminal window
knip --production

To fine-tune the resulting production file set, for instance to exclude test helper files that still show as unused, use the exclamation mark suffix on production patterns:

{
"entry": ["src/index.ts!"],
"project": ["src/**/*.ts!", "!src/test-helpers/**!"]
}

Remember to keep adding the exclamation mark suffix! for production file patterns.

To reiterate, the default entry and project files for each workspace:

{
"entry": [
"{index,cli,main}.{js,cjs,mjs,jsx,ts,cts,mts,tsx}",
"src/{index,cli,main}.{js,cjs,mjs,jsx,ts,cts,mts,tsx}"
],
"project": ["**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}!"]
}

Next to this, there are other places where Knip looks for entry files.

Additionally, plugins have plenty of entry files configured that are automatically added as well.

ISC License © 2024 Lars Kappert