knip alternative: migrate from knip to fallow
Migrate from knip to fallow. One command converts your knip config to a fallow config. See what the command migrates and what to check after the move.
The fallow migrate command translates your knip configuration to a fallow config. This page shows the steps, the field mapping, and the settings that need a manual check.
Migration workflow
Preview the migration
Run
fallow migrate --dry-runto see the generated config. The command writes no files.fallow migrate --dry-runfallow looks for
knip.json,knip.jsonc,.knip.json,.knip.jsonc,knip.ts,knip.config.ts, and theknipfield inpackage.json. Fallow detects the TypeScript config files (knip.ts,knip.config.ts) but cannot parse them. Convert them toknip.jsonfirst.{ "$schema": "https://raw.githubusercontent.com/fallow-rs/fallow/main/schema.json", // Migrated from knip.json "entry": [ "src/index.ts", "src/cli.ts" ], "ignoreFindings": [ "**/*.generated.ts" ], "ignoreDependencies": [ "@types/node" ] } Migrated from: knip.json Warning (1): [knip] `project`: Fallow auto-discovers project files Note: knip and fallow use different glob engines; verify migrated entry / ignoreFindings with `fallow dead-code` before relying on CI. https://fallow.tools/docs/migration/from-knip/ Note: knip's ignore also suppresses dependency and manifest issues by file path; fallow's ignoreFindings never hides manifest-owned findings such as unused dependencies. https://fallow.tools/docs/migration/from-knip/Generate the config
When the preview looks correct, run the migration:
fallow migrate # Write .fallowrc.json fallow migrate --toml # Or output as fallow.tomlReview the config
Open the generated config. Check the translated entry points, ignore patterns, and plugin mappings. Fallow shows a warning for each field that it could not migrate automatically.
Run your first analysis
Run the dead code analysis and examine the findings. Then run the other analyses:
fallow dead-code # Unused code + circular deps + boundaries fallow dupes # Code duplication fallow health # Complexity hotspots + maintainability scores fallow # All of the above in one pass
What gets migrated
| knip | Fallow |
|---|---|
entry | entry, and supportEntry for the patterns without a production marker (see Production entries) |
project | -- (fallow auto-discovers project files) |
ignore | ignoreFindings (matching files stay in the analysis graph) |
ignoreDependencies | ignoreDependencies (a regex becomes a glob when a glob matches the same packages, see Warnings and caveats) |
Workspace ignoreDependencies, includeEntryExports | workspaces.settings keys for the same workspace path |
ignoreExportsUsedInFile | ignoreExportsUsedInFile (boolean and { type, interface } object form both supported) |
rules, include, exclude | rules (knip issue types map to fallow rule names) |
nsExports, nsTypes (in rules, include, exclude, ignoreIssues) | -- (fallow reports these findings as unused-exports and unused-types. Fallow cannot set them apart, so exports and types control them too. The migration warns when a namespace type has another setting than its base type) |
namespaceMembers | unused-namespace-members (in rules, include, exclude and ignoreIssues) |
ignoreBinaries | ignoreBinaries (a regex becomes a glob when a glob matches the same names. A workspace list merges into the global list) |
ignoreGlobalBinaries | -- (no switch for globally installed binaries. The warning suggests ignoreBinaries) |
cycles | -- (no allow-list for exact cycle paths. The warning suggests circularDependencies.ignoreLazyImports or a // fallow-ignore-next-line circular-dependency comment) |
preprocessor, preprocessorOptions | -- (not supported. The warning suggests to post-process the fallow --format json output) |
compilers, asyncCompilers | -- (fallow parses with Oxc and has no custom compilers) |
| Plugin configs | -- (fallow's built-in plugins detect the framework; the migration warns you to remove the section) |
Production entries
A trailing ! marks an entry pattern as a production entry. When the config marks at least one pattern, the migration writes the marked patterns to entry and the other patterns to supportEntry. So fallow dead-code --production uses only the marked entries plus the framework production entries, and a normal run uses all of them. When no pattern has the marker, every pattern goes to entry.
Per-workspace settings
A workspace section can set ignoreDependencies and includeEntryExports. The migration writes them to workspaces.settings, keyed by the workspace path, so they keep their workspace scope. The root workspace . uses the global keys.
Only the most specific workspace section applies in the source config. Fallow merges the ignoreDependencies lists of every matching key. When a glob section such as packages/* has a list and a more specific section also matches, the migration warns, because the more specific workspace now also ignores the glob entries. For includeEntryExports, the migration writes the root value to a more specific section that does not set it, so the result does not change.
Warnings and caveats
fallow migrate warns about each setting that it cannot translate, so you do not lose a setting without notice.
Unknown rule names. Your knip rules, exclude, or include entries can reference a key that fallow does not know. The cause can be a typo, a future knip rule, or an issue type that the migrator does not know yet. The migration then prints a warning like this one:
Warning (1):
[knip] `rules.unsued-files`: unknown knip issue type `unsued-files`; not migrated (suggestion: check for a typo or report the missing mapping at https://fallow.tools/docs/migration/from-knip/)
The binaries issue type maps to the unlisted-binaries rule. Some keys are on the documented list of keys that cannot be mapped: optionalPeerDependencies, and similar issue types that knip reports and fallow does not. For these keys, the warning reads issue type \X` has no fallow equivalent` and has no suggestion.
Glob-engine drift. knip and fallow use different glob engines. The migration copies entry and ignoreFindings verbatim, but they can match a slightly different set of files than in knip. When the migrated config has either field, the migrate command prints:
Note: knip and fallow use different glob engines; verify migrated entry /
ignoreFindings with `fallow dead-code` before relying on CI.
https://fallow.tools/docs/migration/from-knip/
Common patterns (brace expansion {ts,tsx}, double-star **, src/**) match the same files in both engines. ignoreFindings keeps a leading ! as an exception to the earlier patterns. Run fallow dead-code on a representative subset before you use the migrated globs in CI.
Dependency regexes. knip reads an ignoreDependencies entry as a regex when it contains one of * + \ ( | { ^ $. Fallow reads ignoreDependencies entries as exact names or as globs, see ignoreDependencies. The migration converts a regex to a glob only when the glob matches exactly the same package names:
| knip regex | Migrated glob |
|---|---|
@acme/.+ or ^@acme/.+$ | @acme/* |
^@types/ | @types/* |
^eslint-plugin-.*$ | eslint-plugin-* |
-loader$ | *-loader |
^react$ | react |
A regex that has no exact glob form stays out of the config, for example an alternation such as ^(react|vue)$, a character class such as ^@acme/[a-z]+$, or .+ in the middle of a name. The migration prints a warning for each such entry:
Warning (1):
[knip] `ignoreDependencies`: regex pattern `^(react|vue)$` skipped (no glob matches the same packages) (suggestion: rewrite it as a glob such as `@scope/*`, or add each dependency name)
Add the skipped entries by hand as globs or as exact names. After the migration, fallow dead-code names every ignoreDependencies glob that matches no declared dependency, so a glob with a typo does not go unnoticed. See Unmatched config patterns.
Ignore scope. knip's ignore also hides dependency and manifest issues by file path. Fallow's ignoreFindings never hides manifest-owned findings, such as unused dependencies. The migrate command prints a note about this difference for every knip migration.