claude/ai-resources-plugin/skills/knip/SKILL.md
Detect and remove dead code with knip. Use when the user asks to "run knip", "find unused files", "find unused exports", "find unused dependencies", "clean up dead code", "remove dead code", "set up knip", "configure knip", "knip.json", "knip false positive", "knip CI", or mentions a `knip` config, dependency bloat, bundle bloat from unused imports, or tree-shaking unused exports. Covers the configuration-first workflow, confidence-gated deletion, framework-specific gotchas (Next.js 15+, Tailwind, Storybook, Jest, Bun's test runner and `bun build --compile`), monorepos, CI integration, and performance tuning.
npx skillsauth add amhuppert/my-ai-resources knipInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Knip finds unused files, exports, and dependencies across a JavaScript/TypeScript project. It does not find unused imports or local variables inside a file — that is a linter's job (ESLint, Biome). Use knip for project-level dead code; use a linter for file-level dead code.
This file is the spine. Detailed configuration, framework-specific gotchas, monorepo guidance, CI integration, and performance tuning live in references/ and load only when needed.
knip.json / knip.config.ts exists and is producing false positives.Do not use this skill for unused imports/variables inside a file — recommend ESLint's no-unused-vars or Biome instead.
npx knip --version.package-lock.json → npm, pnpm-lock.yaml → pnpm, yarn.lock → yarn, bun.lock / bun.lockb → bun) and install with the matching command, e.g. npm install -D knip.knip.json, knip.jsonc, knip.config.{ts,js}, or a knip key in package.json. If one exists, review it against references/config-patterns.md before running.Even when the user says "just run knip" or "clean up the codebase", configure knip properly before acting on reported issues. Ignoring configuration hints leads to acting on false positives, which deletes code that is actually used.
Read package.json to identify:
workspaces field, pnpm-workspace.yaml, turbo.json, nx.json.If the project is a monorepo, load references/monorepo.md before running knip — monorepo misconfiguration cascades into hundreds of false positives.
npx knip
The output is ordered: configuration hints, then issues. Address hints before issues. A hint typically means knip cannot resolve a plugin, entry, or dependency — fixing it eliminates whole categories of false positives at once.
For unfamiliar layouts (non-standard test dirs, custom build pipelines, no formal monorepo), run npx knip --debug instead — it lists every enabled plugin, its detected entries, and resolved workspace config, so you can confirm knip sees what you expect before deciding what to configure.
Common adjustments (see references/config-patterns.md for the full set):
paths (tsconfig-style) for path aliases that knip can't resolve.references/project-nextjs.mdreferences/project-tailwind.mdreferences/project-storybook.mdreferences/project-jest.mdRe-run knip after each config change. Stop iterating only when the hint section is empty.
package.json (dependencies).package.json (devDependencies).ignoreExportsUsedInFile instead (see references/exports-advanced.md).Removing unused files frequently exposes newly-unused exports and dependencies. Keep iterating until the report is clean (or only contains known, justified false positives).
First — establish whether the package is published or private, because the "public API" heuristics below only apply to published packages:
"private": true in package.json, OR has a real version published on npm): lib/, src/index.*, exports/main targets are real external API. Treat them as load-bearing — get user confirmation before deleting."private": true, no npm publishing): "exports" are just module-graph wiring within the repo. If knip + grep agree nothing imports them, they're internal dead code — verify with grep, then act. The lib/ directory has no external consumers in this case.Do not auto-delete anything in these categories. Use AskUserQuestion to confirm first:
src/index.{ts,tsx,js}, lib/, or paths containing public, api, or matching the exports/main field of package.json — these are likely public API surface.await import(...)), referenced by runtime mechanisms (Next.js routing, Storybook story discovery), or named to suggest plugin-style loading (plugins/*.ts, routes/*.ts).prettier, eslint, husky) or as peer dependencies of another package.You may auto-delete (without asking) only when ALL of the following are true:
--fix with the user's prior approval.Use --fix only AFTER the configuration-first workflow is complete and the hint section is empty.
npx knip --fix # remove unused exports + unused deps from package.json
npx knip --fix --allow-remove-files # also delete unused files
Always run the project's formatter after --fix (see references/ci-integration.md on formatting after fix). Review the diff before committing.
For projects that ship code to users, configure a separate production-mode check and add a "knip:production": "knip --production" script alongside the default "knip" script.
npx knip --production
Production mode strictly analyzes only code that reaches users — tests, stories, dev tooling, and devDependencies are excluded. Use this in addition to the default check, not instead of it. See references/ci-integration.md for the canonical "two checks in CI" pattern.
Important: use --production to exclude tests/stories from "shipping code" analysis. Do not use ignore patterns to exclude tests — that hides real issues.
Production mode includes:
! (e.g., "src/index.ts!", "src/**/*.ts!").start script from package.json.@internal.Production mode excludes:
devDependencies (only dependencies are checked).@internal.No ! markers anywhere → almost everything is reported "unused." This is the #1 production-mode trap. If a plugin doesn't designate production entries for your project (e.g., custom CLI/server builds, Bun's bun build --compile), nothing is in scope until you mark entries with !. Add the script and config together — do not commit a knip:production script with zero ! markers.
Plugins don't always know your production entries. Knip's Bun plugin parses bun test for test entries but does not auto-detect entries from bun build --compile, bun run X script chains, or compile-target CLI binaries. The same is true for any custom build script. Add the real shipping entries to entry with !. Example:
{
"entry": [
"src/main.ts!", // bun build --compile target
"src/cli.ts!" // another binary's entrypoint
]
}
String-referenced entries (Bun.build({entrypoints:[…]}), dynamic import(./${x})). Knip can't trace strings to files. Add such files explicitly to entry, then add ! if they ship.
Type-only exports flagged unused. If types live in dedicated files that are only import type-ed, they may appear unused in production mode. Filter the report with --exclude types, or move types next to the value they describe.
Test helpers / mocks living inside src/. Negate them in the production project pattern: ["src/**/*.ts!", "!src/test-helpers/**!"].
Exports intended as public API but currently unused. Tag with /** @public */ so knip doesn't flag them in default mode. Tag internal-only helpers with /** @internal */ so they're excluded from production-mode reports.
--strict implies --production — and also checks workspace isolation and peerDependencies. Don't pass both flags; pick the strictest one you need.
Don't add the knip:production script bare. The right order:
npx knip run clean (configuration-first workflow, hint section empty).exports targets, server entrypoints. Build scripts, test scripts, install scripts, and dev tooling are NOT production.! to those entries in knip.json.@internal JSDoc tags to exports that are intentionally not part of the shipping surface (test utilities exported for tests, debug helpers).npx knip --production --debug and verify the file list under "Production entries" matches your shipping surface.knip:production script.| Load this | When |
|---|---|
| references/config-patterns.md | Reviewing or authoring a knip config — broad-ignore avoidance, paths, schema, run-without-config, project/entry separation, negation patterns |
| references/monorepo.md | The project has workspaces (workspaces, pnpm-workspace.yaml, Nx, Turborepo) — load BEFORE running knip |
| references/ci-integration.md | Adding knip to CI — cache, max-issues, separate production check, reporters, watch mode |
| references/performance.md | Knip is slow (large codebase or monorepo) — --cache, Bun runtime, workspace filters, issue-type filtering |
| references/exports-advanced.md | Lots of export false positives — JSDoc @public tagging, re-exports/barrels, class members, ignoreExportsUsedInFile, --include-entry-exports |
| references/project-nextjs.md | Project uses Next.js 15 or newer |
| references/project-tailwind.md | Project uses Tailwind CSS (v3 or v4) |
| references/project-storybook.md | Project has a .storybook/ directory or @storybook/* deps |
| references/project-jest.md | Project uses Jest as its test runner |
| references/project-bun-test.md | Project uses Bun's built-in test runner (bun test), bun build --compile, or has scripts like bun test tests/ |
These come up so often they're worth stating up front. Full details in references/config-patterns.md.
ignore field. It hides every issue type in those paths, including legitimate ones. Use targeted options instead (ignoreFiles, ignoreDependencies, ignoreExportsUsedInFile)..gitignore paths. Knip already respects .gitignore — listing node_modules, dist, build, .git is redundant.vite.config.ts) when they're flagged unused. Enable or disable the relevant plugin instead.entry. Auto-detected plugins already add their standard entry points. Custom entry overrides defaults — it does not merge.ignore to exclude tests/stories. Use --production with !-suffixed entry markers.buffer or process): add to ignoreDependencies.| Symptom | Cause | Fix |
|---|---|---|
| Exit code 2 with "error loading file" | Knip can't parse a config or source file | Create or fix knip.json at the project root; check the file knip names in the error |
| "Unable to find a configuration file" | No knip config and project has unusual layout | Create a minimal knip.json with {"$schema":"https://unpkg.com/knip@5/schema.json"} and let plugins auto-configure |
| Hundreds of false positives in a monorepo | Workspaces not configured | Load references/monorepo.md |
| ts-jest reported unused after renaming jest config to .mjs | Known knip issue with .mjs Jest configs | See references/project-jest.md |
| @storybook/builder-vite reported unused | Known knip issue with core.builder reference | See references/project-storybook.md |
npx knip # default run (all code, all deps, all entries)
npx knip --production # shipping code only (excludes tests, stories, dev tooling)
npx knip --fix # auto-remove unused exports and devDependencies
npx knip --fix --allow-remove-files # also delete unused files
npx knip --reporter json # JSON output for parsing/CI
npx knip --include files,dependencies # report only specific issue types
npx knip --cache # use cache for faster repeat runs
npx knip --debug # verbose output, useful for diagnosing missed entries
tools
Use when picking or vetting a keyboard shortcut on macOS. Triggers include "what hotkey should I use for X", "is `<combo>` available", "does this shortcut conflict", "recommend a keybinding for…", "check `<combo>` against my setup", "pick a hotkey for…", or any mention of choosing/binding/changing a shortcut in WezTerm, tmux, Zed, Chrome, Claude Code, or macOS. Determines whether a proposed combo collides with OS-reserved bindings, app defaults, or the user's customizations, and recommends ergonomic alternatives when needed.
tools
This skill should be used when the user asks to "set up react-scan", "install react-scan", "diagnose React re-renders", "find unnecessary renders", "find unstable props", "automate React render checks with Playwright", "react-scan + playwright", "measure component renders programmatically", "check why a React component is slow", or mentions React rendering issues, slow React interactions, render counts, or component-level perf attribution. Covers install across Next.js/Vite/Remix/script-tag/browser-extension, the lite headless API for CI, and the canonical render-attribution → fix → validate loop driven through Playwright.
documentation
This skill should be used when integrating source material into a knowledge base, including when the user asks to "integrate this document into the knowledge base", "add this transcript to the memory bank", "ingest this document", "update the knowledge base", "analyze a new source document", or "sync current-state docs with this source".
tools
--- name: kb-ingest description: Delegate knowledge-base ingestion to the `knowledge-base-ingester` sub-agent so the source document, primary/current trees, and ingest workflow stay out of the main conversation's context window. Run this when the user explicitly invokes `/ai-resources:kb-ingest`; do not auto-trigger from natural-language ingestion requests (those should use the `knowledge-base-ingest` skill directly). disable-agent disable-model-invocation: true --- # kb-ingest Run a knowledge