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 type | rev-dep check | Notes |
|---|---|---|
dependencies | unusedNodeModulesDetection | Declared but unused dependencies. |
devDependencies | unusedNodeModulesDetection | Unused devDependencies surface as unused declared modules. |
unlisted | missingNodeModulesDetection | Imports not declared in package.json. |
unresolved | unresolvedImportsDetection | Import requests that don't resolve. |
exports | unusedExportsDetection | Unused exports. |
types | unusedExportsDetection | Covered while ignoreTypeExports is false (the default). |
files | orphanFilesDetection | Unused/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. |
| - | circularImportsDetection | New capability. |
| - | moduleBoundaries | New capability. |
| - | restrictedImportsDetection | New capability. |
| - | importConventions | New capability. |
| - | devDepsUsageOnProdDetection | New 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 option | rev-dep equivalent |
|---|---|
entry | prodEntryPoints (and devEntryPoints for tests/tooling) |
project | the rule's path - rev-dep discovers all files under it (respecting .gitignore and ignoreFiles) |
workspaces | one entry in rules per package |
ignoreDependencies | excludeModules on the node-modules checks |
ignore | per-check ignoreFiles, or top-level ignoreFiles or ignoreEntryPoints |
ignoreUnresolved | ignoreImports / ignoreFiles on unresolvedImportsDetection |
paths | declared 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​
- Verify resolution first with
unresolvedImportsDetection- see the monorepo integration guide. - In a monorepo, run unused-exports and orphan-file checks at the root so cross-package usage is visible: orphan files and unused exports in shared packages.