knip icon indicating copy to clipboard operation
knip copied to clipboard

🧩 Knip takes a long amount of time in our codebase

Open nandita1 opened this issue 1 month ago • 8 comments

Discuss anything related to Knip

We have a fairly large codebase (around ~121370 lines of code) with a multi package architecture and knip takes around more than 1-1.5 hrs to run whereas depcheck only takes a few minutes. I only want to check for unused dependencies. Also running into OOM issues most of the times in a node.js script even with NODE_OPTIONS="--max-old-space-size=24576". Here is my knip.json file:

{
  "$schema": "https://unpkg.com/knip@5/schema.json",
  "ignore": [
    "**/*.spec.{ts,tsx}",
    "**/*.stories.{ts,tsx}",
    "**/*.test.{ts,tsx}",
    "**/generated/**",
    "**/node_modules/**",
    "**/build_output/**",
    "**/dist/**",
    "tools/**",
    "mock/**",
    ".storybook/**"
  ],
  "ignoreDependencies": ["@types/*", "typescript"],
  "ignoreExportsUsedInFile": true,
  "ignoreWorkspaces": ["tools/**"],
  "workspaces": {
    ".": {
      "entry": [
        "src/index.tsx",
        "config/**/*.{ts,tsx,js,mjs}",
        "vite.*.ts",
        "vite.*.mts",
        "babel.config.js",
        "jest.config.js",
        ".storybook/**/*.{ts,tsx,js}"
      ],
      "ignore": [
        "src/generated/**",
        "build_output/**",
        "dist/**",
        "node_modules/**",
        "**/*.spec.{ts,tsx}",
        "**/*.stories.{ts,tsx}",
        "**/*.test.{ts,tsx}",
        "tools/**",
        "mock/**"
      ],
      "ignoreDependencies": [
        "@types/*",
        "typescript",
        "eslint",
        "prettier",
        "jest",
        "@testing-library/*",
        "vite",
        "babel-*",
        "@babel/*",
        "webpack",
        "webpack-*"
      ],
      "project": [
        "src/**/*.{ts,tsx}",
        "config/**/*.{ts,tsx,js,mjs}",
        "!src/**/*.spec.{ts,tsx}",
        "!src/**/*.stories.{ts,tsx}",
        "!src/**/*.test.{ts,tsx}",
        "!src/generated/**",
        "!**/generated/**",
        "!**/node_modules/**",
        "!**/build_output/**",
        "!**/dist/**"
      ]
    },
    "packages/*": {
      "entry": ["src/index.barrel.tsx", "src/**/*.routes.tsx"],
      "ignore": [
        "generated/**",
        "dist/**",
        "node_modules/**",
        "**/*.spec.{ts,tsx}",
        "**/*.stories.{ts,tsx}",
        "**/*.test.{ts,tsx}"
      ],
      "ignoreDependencies": [
        "@types/*",
        "typescript",
        "eslint",
        "prettier",
        "jest",
        "@testing-library/*"
      ],
      "project": [
        "src/**/*.{ts,tsx}",
        "!src/**/*.spec.{ts,tsx}",
        "!src/**/*.stories.{ts,tsx}",
        "!src/**/*.test.{ts,tsx}",
        "!generated/**",
        "!**/generated/**",
        "!**/node_modules/**",
        "!**/build_output/**",
        "!**/dist/**"
      ]
    },
    "packages/snappables/*": {
      "entry": ["src/index.barrel.tsx", "src/**/*.routes.tsx"],
      "ignore": [
        "generated/**",
        "dist/**",
        "node_modules/**",
        "**/*.spec.{ts,tsx}",
        "**/*.stories.{ts,tsx}",
        "**/*.test.{ts,tsx}"
      ],
      "ignoreDependencies": [
        "@types/*",
        "typescript",
        "eslint",
        "prettier",
        "jest",
        "@testing-library/*"
      ],
      "project": [
        "src/**/*.{ts,tsx}",
        "!src/**/*.spec.{ts,tsx}",
        "!src/**/*.stories.{ts,tsx}",
        "!src/**/*.test.{ts,tsx}",
        "!generated/**",
        "!**/generated/**",
        "!**/node_modules/**",
        "!**/build_output/**",
        "!**/dist/**"
      ]
    }
  }
}

Running the command as - NODE_OPTIONS="--max-old-space-size=24576" npx knip --include=dependencies,devDependencies --reporter json --config knip.json

nandita1 avatar Jan 02 '26 05:01 nandita1

Looking at the configuration, and the fact that there is no rep(r)o for us to look at, I'd say you roughly have two roads to follow here:

  • Read/translate the documentation at https://knip.dev — what part is unclear or missing? What have you tried already?
  • Using an IDE like VS Code or Cursor, the new Knip Editor Extension and a good model like Opus 4.5, tell it something like "fix Knip config" (bonus tip: also tell it to limit runs to e.g. 5 minutes)

I am here to help. That configuration tells me there is room for improvement in both your config and our docs and I'd love to figure out how to better prevent users from ending up in a situation like yours.

webpro avatar Jan 02 '26 06:01 webpro

hey @nandita1 would be great to see the reproduction. The config looks normal. I'm running Knip in our 3.5M lines repo with more than 750 packages, and it takes around 35 min. You can use --debug or --performance to identify what is causing this. https://knip.dev/reference/cli#--performance

wamujlb avatar Jan 02 '26 09:01 wamujlb

The config looks normal.

Why do you think that's the case? It's pretty wild to me you come in here and make the statement. Honestly interested to hear opinions here.

webpro avatar Jan 02 '26 09:01 webpro

I have had a similar issue when I had too many entry files due to the the issue with exports. I wasn't not clear I think when I said that "the config looks normal", I have meant the issue with entries. The config definitely needs some improvement, but without repro it's difficult to say which. All these ignore, ignoreDependencies and project don't seem right.

wamujlb avatar Jan 02 '26 10:01 wamujlb

Reproducing this will be difficult as I am not sure what the exact reason might be. @webpro I tried what you said and augment made the config a bit more concise and mainly added "exclude": ["classMembers", "enumMembers"]

{
  "$schema": "https://unpkg.com/knip@5/schema.json",
  "exclude": ["classMembers", "enumMembers"],
  "ignoreDependencies": [
    "@types/*",
    "typescript",
    "eslint",
    "prettier",
    "jest",
    "@testing-library/*",
    "@graphql-codegen/*"
  ],
  "ignoreExportsUsedInFile": true,
  "ignoreWorkspaces": ["tools/**"],
  "workspaces": {
    ".": {
      "entry": [
        "src/index.tsx",
        "config/**/*.{ts,tsx,js,mjs}",
        "vite.*.ts",
        "vite.*.mts",
        "babel.config.js",
        "jest.config.js"
      ],
      "ignoreDependencies": [
        "vite",
        "babel-*",
        "@babel/*",
        "webpack",
        "webpack-*",
        "lodash",
        "meow",
        "ajv",
        "better-ajv-errors",
        "tsconfig-paths",
        "@rubrik/settings"
      ],
      "project": [
        "src/**/*.{ts,tsx}",
        "config/**/*.{ts,tsx,js,mjs}",
        "!src/**/*.spec.{ts,tsx}",
        "!src/**/*.stories.{ts,tsx}",
        "!src/**/*.test.{ts,tsx}",
        "!src/**/*.mocks.{ts,tsx}",
        "!src/generated/**"
      ]
    },
    "packages/*": {
      "entry": ["src/index.barrel.tsx", "src/**/*.routes.tsx"],
      "project": [
        "src/**/*.{ts,tsx}",
        "config/**/*.{ts,tsx,js,mjs}",
        "!src/**/*.spec.{ts,tsx}",
        "!src/**/*.stories.{ts,tsx}",
        "!src/**/*.test.{ts,tsx}",
        "!src/**/*.mocks.{ts,tsx}"
      ]
    },
    "packages/snappables/*": {
      "entry": ["src/index.barrel.tsx", "src/**/*.routes.tsx"],
      "project": [
        "src/**/*.{ts,tsx}",
        "!src/**/*.spec.{ts,tsx}",
        "!src/**/*.stories.{ts,tsx}",
        "!src/**/*.test.{ts,tsx}",
        "!src/**/*.mocks.{ts,tsx}"
      ]
    }
  }
}

But still no improvements. I am trying to get the output from --debug --performance but will take some time

nandita1 avatar Jan 02 '26 10:01 nandita1

The only thing I want to add at this point as that one should definitely not wait >10 minutes for any run, especially when iterating on the config. There is clearly something off as 121K LOC isn't that much.

Make sure you know about production mode, focus on small/stand-alone workspaces first, --debug/--performance those, perhaps even --isolate-workspaces, enable/disable plugins, and so on.

webpro avatar Jan 02 '26 10:01 webpro

Oh ignoreExportsUsedInFile slows things down too (you mentioned looking for unused deps only anyway).

webpro avatar Jan 02 '26 10:01 webpro

Preview release available:

npm i -D https://pkg.pr.new/knip@e031018

github-actions[bot] avatar Jan 04 '26 14:01 github-actions[bot]

Re: normal config

I see that often in knip configs: a lot of ignored paths, repeated multiple times in every workspace. https://github.com/webpro-nl/knip/issues/1064 at the root would help here.

fregante avatar Jan 11 '26 19:01 fregante

No, respecting .npmignore wouldn't help. Just closed that ticket with some reasoning.

webpro avatar Jan 11 '26 20:01 webpro