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 get the most value and performance out of Knip.

TL;DR;

  • Start with defaults. Only add targeted entry overrides when needed.
  • Use project patterns (with negations) to define “what belongs to the codebase” for unused file detection.
  • 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 is this better:

  • project defines “what belongs to the codebase” so build outputs are not part of the analysis and don’t appear in unused file detection at all
  • ignore is for the few files that should be analyzed but contain exceptions
  • increases performance by analyzing only source 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 only 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 for test frameworks add test file as entry files, you can’t and shouldn’t override that globally.

❌   Or this:

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

Why not: project is used for unused file detection. Negating test files here is ineffective, because they’re 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