Skip to main content

Migrating from knip

knip finds unused files, exports, and dependencies in JavaScript/TypeScript projects. rev-dep covers that same core, adds architecture checks knip does not have, and runs as a single Go-powered pass.

Why migrate​

  • Speed. knip runs on Node; rev-dep is written in Go and runs every check in one parallel pass - up to 20x faster on large codebases, which keeps it cheap to run on every PR.
  • More than unused code. knip focuses on unused files/exports/dependencies. rev-dep does that and enforces architecture - circular imports, module boundaries, restricted imports, import conventions, and dev-dependencies in production - so it can replace several tools at once.
  • Built for monorepos. A single config runs per-workspace rules in parallel and resolves cross-package imports, with whole-repo context when you need it.

What carries over, what changes​

  • Covered well: unused files, unused exports, unused dependencies, unlisted (missing) dependencies, unresolved imports.
  • rev-dep adds: circular imports, module boundaries, restricted imports, import conventions, and dev-dependencies-in-production.
  • Not replaced: knip's more granular reports - unused class/enum members, namespace-level exports, duplicate exports, unused catalog entries, and missing/optional binaries - have no equivalent in rev-dep, which works at the file/export/dependency level.

Feature mapping​

knip issue typerev-dep checkNotes
dependenciesunusedNodeModulesDetectionDeclared but unused dependencies.
devDependenciesunusedNodeModulesDetectionUnused devDependencies surface as unused declared modules.
unlistedmissingNodeModulesDetectionImports not declared in package.json.
unresolvedunresolvedImportsDetectionImport requests that don't resolve.
exportsunusedExportsDetectionUnused exports.
typesunusedExportsDetectionCovered while ignoreTypeExports is false (the default).
filesorphanFilesDetectionUnused/unreachable files.
binaries-No equivalent.
catalog-No equivalent.
duplicates-No equivalent.
classMembers, enumMembers-rev-dep has no member-level detector.
nsExports, nsTypes-rev-dep has no namespace-member detector.
-circularImportsDetectionNew capability.
-moduleBoundariesNew capability.
-restrictedImportsDetectionNew capability.
-importConventionsNew capability.
-devDepsUsageOnProdDetectionNew capability.

Translating your config​

knip infers most things from your entry and project globs. rev-dep is rule-based: each rule targets a path (usually a workspace) and enables checks explicitly.

A typical knip.json:

{
"entry": ["src/index.ts", "src/cli.ts"],
"project": ["src/**/*.ts"],
"ignore": ["**/*.stories.tsx"],
"ignoreDependencies": ["husky", "@types/jest"]
}

becomes a rev-dep.config.jsonc:

{
"rules": [
{
"path": ".",
"prodEntryPoints": ["src/index.ts", "src/cli.ts"],
"ignoreEntryPoints": ["**/*.stories.tsx"]
"unresolvedImportsDetection": {
"enabled": true
},
"missingNodeModulesDetection": {
"enabled": true
},
"unusedNodeModulesDetection": {
"enabled": true,
"excludeModules": ["husky", "@types/jest"]
},
"orphanFilesDetection": {
"enabled": true,
},
"unusedExportsDetection": {
"enabled": true
}
}
]
}

Key translations:

knip optionrev-dep equivalent
entryprodEntryPoints (and devEntryPoints for tests/tooling)
projectthe rule's path - rev-dep discovers all files under it (respecting .gitignore and ignoreFiles)
workspacesone entry in rules per package
ignoreDependenciesexcludeModules on the node-modules checks
ignoreper-check ignoreFiles, or top-level ignoreFiles or ignoreEntryPoints
ignoreUnresolvedignoreImports / ignoreFiles on unresolvedImportsDetection
pathsdeclared in tsconfig.json paths (rev-dep reads them automatically)

For per-check ignore options and the exact data shapes, see Ignoring files.

Running it​

# knip
npx knip

# rev-dep
rev-dep config run
rev-dep config run --fix # applies autofixes (unused exports, orphan files, import conventions)

Both exit non-zero when issues are found, so the CI swap is direct. See running checks and autofix.

Next steps​