Profiles

Profiles are one of the biggest features in npkill 1.0. They let you clean up much more than just node_modules — think Python virtual environments, Rust build artifacts, game engine caches, and more.

What are Profiles?

A profile is a collection of target directories that belong together. Instead of specifying individual targets, you can use a profile to search for all related directories at once.

For example, the node profile includes not just node_modules, but also .next, .nx, .angular, .turbo, and other heavy directories commonly found in Node.js projects.

Some folders are found by name alone. Others only count when the files that identify their project are around them. For example, target is only shown next to a Cargo.toml, pom.xml or build.sbt.

Using Profiles

Use the -p or --profiles flag:

npx npkill -p python

Separate several profiles with commas:

npx npkill -p node,python

By default, npkill uses the node profile. all combines every built-in profile, including your overrides of them.

Available Profiles

npkill 1.0 ships with 20 built-in profiles. Run npkill --profiles to see all of them.

Profile Targets Found when
node node_modules, .angular Always
node .next, .nuxt, .svelte-kit, .parcel-cache Next to package.json
node .nx Next to nx.json
node .output Contains nitro.json
node .vite Contains deps
node .turbo Next to turbo.json or turbo.jsonc
node storybook-static Next to package.json and .storybook, contains index.html and iframe.html
node .docusaurus Contains DONT-EDIT-THIS-FOLDER
node coverage Contains coverage-final.json, lcov.info or clover.xml
python __pycache__ Always
python .pytest_cache, .mypy_cache, .ruff_cache Contains CACHEDIR.TAG
python .tox Next to tox.ini, tox.toml, pyproject.toml or setup.cfg
python .nox Next to noxfile.py
python .venv, venv, env Contains pyvenv.cfg
java target Next to pom.xml
java build Next to build.gradle or build.gradle.kts
java .gradle Next to settings.gradle, settings.gradle.kts, build.gradle or build.gradle.kts
android build, .cxx Next to build.gradle or build.gradle.kts
dotnet obj Contains project.assets.json
rust target Next to Cargo.toml
elixir _build, deps Next to mix.exs
elixir .elixir_ls Always
haskell dist-newstyle Contains cache
haskell .stack-work Always
scala target Next to build.sbt or build.properties
scala .bloop, .metals Next to build.sbt
cpp CMakeFiles Next to CMakeCache.txt or cmake_install.cmake
cpp cmake-build-debug, cmake-build-release Contains CMakeCache.txt
unity Library Next to Assets and ProjectSettings. Unity reimports every asset afterwards
unreal Intermediate, DerivedDataCache Next to Config and Content
godot .import, .godot Next to project.godot. Includes local editor state and export credentials
clojure .cpcache Next to deps.edn
elm elm-stuff Next to elm.json
php vendor Next to composer.json, contains autoload.php
dart .dart_tool, build Next to pubspec.yaml
swift .build Next to Package.swift
zig .zig-cache, zig-cache, zig-out Next to build.zig
terraform .terraform Next to .terraform.lock.hcl. The selected workspace goes back to default
npkill header with the result counter for the node profile
The result counter shows which profiles are active and how many items were found for each target type.

Profiles and Custom Targets

--targets searches only for the names you give and turns profiles off. It can't be combined with -p. To search for extra folders together with a profile, create your own profile in .npkillrc.

npx npkill --targets ".tmp,coverage"

Custom Profiles

You can create your own profiles in the .npkillrc configuration file:

~/.npkillrc
{
  "profiles": {
    "webdev": {
      "description": "Frontend web development artifacts",
      "targets": ["dist", ".next", ".nuxt", ".output"]
    },
    "mystack": {
      "description": "Full-stack project artifacts (JS/Python/Java)",
      "targets": ["venv", ".venv", "target", "__pycache__", ".gradle"]
    },
    "mobile": {
      "description": "Mobile platform build folders and caches",
      "targets": ["Pods", "build", "DerivedData", "gradle"]
    }
  }
}

Custom profiles will override built-in profiles with the same name. all is reserved.

Custom rules

Targets take folder names and rules in the same list:

"targets": [
  "_opam",
  { "target": "_build", "nextTo": ["dune-project"] },
  { "target": "_build", "nextTo": ["dune-workspace"] }
]
  • A name finds every folder called that way. --targets works the same.
  • A rule needs nextTo, contains or both. Every entry listed must exist.
  • Rules with the same target are alternatives. Any of them is enough.
  • Entries are plain names compared exactly, case included. Paths and the characters * ? [ ] { } / \ are rejected.
  • Unknown properties are rejected.

Why Profiles Matter

Before npkill 1.0, you had to manually specify targets or run npkill multiple times for different project types. Profiles solve this by grouping related directories together, making it easy to clean up entire development stacks with a single command.

Pro tip: Set defaultProfiles in your .npkillrc so npkill always uses your preferred profiles.