> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fallow.tools/llms.txt
> Use this file to discover all available pages before exploring further.

# Fallow vs Knip

> Compare fallow and knip for TypeScript and JavaScript codebase analysis. Side-by-side benchmarks, detection capabilities, plugin coverage, and when to choose each tool. Fallow also covers duplication, complexity, and architecture boundaries.

Fallow and knip both detect unused code in TypeScript and JavaScript projects. Knip is a mature tool with broad plugin coverage. Fallow is a Rust-native alternative that goes beyond unused code: it also covers code duplication, complexity hotspots, maintainability scoring, and architecture boundary enforcement in a single binary.

Use this comparison to decide which tool fits your project.

## Performance

Fallow is a compiled Rust binary with rayon-based parallelism. Knip runs on Node.js. Version 6 adopted the Oxc parser via NAPI bindings, which significantly narrowed the gap with v5, but knip remains single-threaded.

<Tabs>
  <Tab title="Real-world projects">
    | Project                                             |  Files |    fallow | knip v5 | knip v6 |   vs v5 |    vs v6 |
    | :-------------------------------------------------- | -----: | --------: | ------: | ------: | ------: | -------: |
    | [zod](https://github.com/colinhacks/zod)            |    174 |  **25ms** |   650ms |   330ms | **26x** |  **13x** |
    | [preact](https://github.com/preactjs/preact)        |    244 | **200ms** |   911ms |   2.15s |  **5x** |  **11x** |
    | [fastify](https://github.com/fastify/fastify)       |    286 |  **27ms** |   933ms |   222ms | **34x** |   **8x** |
    | [vue/core](https://github.com/vuejs/core)           |    522 |  **68ms** |   ---\* |   ---\* |     --- |      --- |
    | [TanStack/query](https://github.com/TanStack/query) |    901 | **330ms** |   2.66s |   1.08s |  **8x** | **3.3x** |
    | [vite](https://github.com/vitejs/vite)              |  1,420 | **378ms** |   ---\* |   ---\* |     --- |      --- |
    | [svelte](https://github.com/sveltejs/svelte)        |  3,337 | **363ms** |   1.95s |   714ms |  **5x** |   **2x** |
    | [next.js](https://github.com/vercel/next.js)        | 20,416 | **1.72s** |   ---\* |   ---\* |     --- |      --- |
  </Tab>

  <Tab title="Synthetic benchmarks">
    | Project size |    fallow | knip v5 | knip v6 |   vs v5 |  vs v6 |
    | :----------- | --------: | ------: | ------: | ------: | -----: |
    | 1,000 files  |  **35ms** |   477ms |   232ms | **14x** | **7x** |
    | 5,000 files  | **144ms** |   791ms |   421ms |  **5x** | **3x** |
  </Tab>
</Tabs>

<Info>
  Benchmarked on 8 real-world open-source projects from 174 to 20,416 files against fallow 2.46.0, knip 5.87.0, and knip 6.6.1 on Apple M5, 32 GB RAM, Node 22. Median of 5 runs with 2 warmups. On small-to-medium projects, fallow is 5-34x faster than knip v5 and 2-13x faster than knip v6. On the current vite, next.js, and vue/core fixtures, knip errors out without producing valid JSON results; fallow is the only tool that completes. \* knip errors on next.js, vite, and vue/core (exits without valid results).
</Info>

### Why fallow is faster

| Factor      | fallow                               | knip                               |
| :---------- | :----------------------------------- | :--------------------------------- |
| Language    | Compiled Rust binary                 | Node.js runtime                    |
| Parser      | Oxc (native Rust)                    | Oxc via NAPI bindings              |
| Parallelism | rayon work-stealing across all cores | Single-threaded                    |
| Startup     | Instant (no JIT warmup)              | Node.js bootstrap + module loading |
| Memory      | Flat contiguous data structures      | GC-managed heap                    |

### Memory and large codebases

Fallow uses flat edge storage and lock-free parallel resolution, so it handles large monorepos well. Memory usage scales linearly with file count rather than with the Node.js GC heap.

## Detection capabilities

<Tabs>
  <Tab title="Comparison table">
    | Capability                           |           fallow           |        knip        |
    | :----------------------------------- | :------------------------: | :----------------: |
    | Unused files                         |             Yes            |         Yes        |
    | Unused exports                       |             Yes            |         Yes        |
    | Unused types                         |             Yes            |         Yes        |
    | Unused dependencies                  |             Yes            |         Yes        |
    | Unused devDependencies               |             Yes            |         Yes        |
    | Unused enum members                  |             Yes            |         Yes        |
    | Unused class members                 |             Yes            | No (dropped in v6) |
    | Unresolved imports                   |             Yes            |         Yes        |
    | Unlisted dependencies                |             Yes            |         Yes        |
    | Duplicate exports                    |             Yes            |         No         |
    | Code duplication                     |    Yes (`fallow dupes`)    |         No         |
    | Circular dependencies                |             Yes            |         Yes        |
    | Complexity hotspots                  |    Yes (`fallow health`)   |         No         |
    | Architecture boundary violations     |             Yes            |         No         |
    | Feature flag detection               |    Yes (`fallow flags`)    |         No         |
    | CRAP score thresholds (`--max-crap`) |             Yes            |         No         |
    | Runtime coverage (paid)              | Yes (`--runtime-coverage`) |         No         |
    | TS namespace declaration members     |             No             |   Yes (new in v6)  |
  </Tab>

  <Tab title="Details">
    **Fallow extras:**

    * **Unused class members**: Knip dropped class member detection in v6. Fallow retains it with whole-object-use heuristics (`Object.values`, `Object.keys`, `for..in`, spread, computed access).
    * **Duplicate exports**: Detects the same symbol exported from multiple modules, helping clean up barrel file sprawl.
    * **Code duplication**: Built-in `fallow dupes` command with four detection modes (strict, mild, weak, semantic), clone family grouping, and refactoring suggestions. No need for a separate tool like jscpd.
    * **Circular dependencies**: Detected via the module graph. Both fallow and knip support circular dependency detection.
    * **Namespace import narrowing**: `import * as ns from './x'` followed by `ns.foo` or `const { foo } = ns` narrows to only mark accessed exports as used. Includes scope-aware unused import binding detection via `oxc_semantic`. Imports where the binding is never read don't count as references.
    * **Complexity hotspots**: `fallow health` reports per-function cyclomatic and cognitive complexity, CRAP (Change Risk Anti-Patterns) score with optional Istanbul coverage, unit size, and a composite health score. `--max-crap`, `--max-cyclomatic`, and `--max-cognitive` gate CI on thresholds.
    * **Architecture boundary violations**: Enforces cross-package or cross-layer import rules declared in config. Flags imports that cross defined boundaries.
    * **Feature flag detection**: `fallow flags` scans for feature flag patterns, correlates them with dead code, and outputs SARIF / markdown / JSON / MCP.
    * **Runtime coverage (paid)**: Merges V8 runtime samples with the static graph to surface hot / cold paths and runtime-weighted health.

    **Knip extras:**

    * **TS namespace declaration members**: New in v6, detecting unused members of TypeScript `namespace` declarations (the `namespace Foo { export const bar }` syntax).
  </Tab>
</Tabs>

## Plugin coverage

| Metric                      | fallow                             | knip               |
| :-------------------------- | :--------------------------------- | :----------------- |
| Total plugins               | 94                                 | 147                |
| Plugins with config parsing | 33                                 | --                 |
| Custom plugin support       | Yes (JSONC, JSON, TOML, or inline) | Yes (JS functions) |

Knip has broader plugin coverage, particularly for niche and legacy tooling. Fallow covers all major frameworks and the most popular tools across every category.

<Tabs>
  <Tab title="Shared coverage">
    Both tools have plugins for: Next.js, Nuxt, Remix, SvelteKit, Gatsby, Astro, Angular, NestJS, Vite, Webpack, Rollup, Vitest, Jest, Playwright, Cypress, Storybook, ESLint, Biome, TypeScript, Babel, Tailwind, PostCSS, Prisma, Turborepo, Nx, semantic-release, and many more.
  </Tab>

  <Tab title="Fallow-only plugins">
    Rspack, Rsbuild, Rolldown, Tsdown, Drizzle, Knex, Kysely, TypeORM, Wrangler (Cloudflare), Expo, React Native, Electron, i18next, Parcel, Oxlint, SWC, WebdriverIO, Cucumber, lefthook, Docusaurus, Capacitor, typedoc, c8/nyc, markdownlint, Remark, and others.
  </Tab>

  <Tab title="Knip-only plugins">
    Knip covers additional tools like Wireit, GitHub Actions, Netlify, and several other niche integrations. Check the [knip plugin list](https://knip.dev/reference/plugins) for the full inventory.
  </Tab>
</Tabs>

<Info>
  If your project uses a framework that fallow doesn't have a plugin for, you can [create a custom plugin](/frameworks/custom-plugins) in JSONC, JSON, or TOML. No code required.
</Info>

## Features fallow has that knip doesn't

<CardGroup cols={2}>
  <Card title="SARIF output" icon="file-code">
    Upload results directly to GitHub Code Scanning with `--format sarif`. Integrated into your PR review workflow.
  </Card>

  <Card title="Baseline comparison" icon="code-compare">
    `--save-baseline` and `--baseline` for incremental CI adoption. Only fail on new issues, not pre-existing ones.
  </Card>

  <Card title="Inline suppression" icon="comment-slash">
    `// fallow-ignore-next-line` and `// fallow-ignore-file` comments for granular, per-line suppression without config changes.
  </Card>

  <Card title="Code duplication" icon="clone">
    Built-in `fallow dupes` with four detection modes, clone family grouping, cross-language matching, and refactoring suggestions.
  </Card>

  <Card title="Complexity and health score" icon="heart-pulse">
    `fallow health` reports cyclomatic / cognitive complexity, CRAP score, risk profiles, and a composite health score. `--max-crap`, `--max-cyclomatic`, and `--max-cognitive` gate CI on per-function thresholds.
  </Card>

  <Card title="Architecture boundaries" icon="shield">
    Enforce cross-package or cross-layer import rules. Boundary violations fail the build without needing ESLint plugins.
  </Card>

  <Card title="Feature flag detection" icon="flag">
    `fallow flags` detects feature flag patterns across the codebase, cross-references them with dead code, and exports to SARIF, markdown, and MCP.
  </Card>

  <Card title="Combined audit" icon="clipboard-check">
    `fallow audit` runs dead code, health, and duplication with a single verdict. Per-analysis baselines (`--dead-code-baseline`, `--health-baseline`, `--dupes-baseline`) let each slice use its own reference.
  </Card>

  <Card title="Standalone rule explainer" icon="circle-question">
    [`fallow explain <issue-type>`](/cli/explain) prints rule rationale, a worked example, fix guidance, and the docs URL without running analysis. Knip has no equivalent. Closest analogs are Credo (`mix credo explain`) for Elixir and Biome's build-time diagnostic explainer; only fallow ships a standalone CLI subcommand plus an MCP tool (`fallow_explain`) that agents can call before fixing a finding.
  </Card>

  <Card title="Git-aware analysis" icon="code-branch">
    `--changed-since <ref>` for file-level scoping and `--changed-workspaces <ref>` for monorepo-level scoping. Perfect for PR-only CI checks.
  </Card>

  <Card title="Workspace filtering" icon="layer-group">
    `--workspace` accepts comma-separated values, globs, and `!` negations (`-w 'apps/*' -w '!apps/legacy'`). Works across every command.
  </Card>

  <Card title="Output grouping" icon="folder-tree">
    `--group-by owner|directory|package|section` partitions findings. `owner` and `section` read GitHub / GitLab CODEOWNERS so unused code is routed to the right reviewer.
  </Card>

  <Card title="Auto-fix dry run" icon="wand-magic-sparkles">
    Preview all fixes with `fallow fix --dry-run` before applying. JSON output for programmatic review.
  </Card>

  <Card title="Trace and debug tooling" icon="magnifying-glass">
    `--trace FILE:EXPORT` to trace export usage chains, `--trace-file PATH` for file edges, `--trace-dependency PACKAGE` for dependency usage, `--performance` for pipeline timing.
  </Card>

  <Card title="CSS Modules tracking" icon="paintbrush">
    `.module.css` and `.module.scss` class names are extracted as named exports and tracked through `styles.className` member accesses.
  </Card>

  <Card title="MCP server" icon="robot">
    Built-in `fallow-mcp` exposes `analyze`, `find_dupes`, `check_health`, `audit`, `check_runtime_coverage`, and more as typed tools for AI agents.
  </Card>

  <Card title="Claude Code hooks" icon="hammer">
    `fallow hooks install --target agent` installs a `PreToolUse` gate that blocks `git commit` / `git push` when `fallow audit` fails, with a structured envelope agents can act on.
  </Card>
</CardGroup>

**Additional features:**

* **Class member detection**: Knip dropped this in v6; fallow retains it with decorator-aware skip logic for NestJS, Angular, TypeORM, etc.
* **Production mode**: `--production` excludes test/dev files and detects type-only dependencies that should be devDependencies.
* **Duplicate export detection**: Finds the same symbol exported from multiple modules.
* **TOML configuration**: In addition to JSONC/JSON, fallow supports `fallow.toml` for teams that prefer TOML.
* **Cross-reference analysis**: `check --include-dupes` finds dead code that is also duplicated, showing high-priority cleanup targets.
* **Runtime coverage intelligence (paid)**: V8 runtime evidence merged with static analysis via a signed sidecar. Adds hot/cold paths, runtime-weighted health scoring, and stale-flag evidence.

## Features knip has that fallow doesn't

<CardGroup cols={2}>
  <Card title="More plugins" icon="puzzle-piece">
    147 plugins vs 94. Knip covers more niche, legacy, and ecosystem-specific tooling.
  </Card>

  <Card title="Custom reporters" icon="paintbrush">
    Write custom reporter functions in JavaScript for fully custom output formatting.
  </Card>

  <Card title="Tags filtering" icon="tags">
    `--tags` flag filters results based on JSDoc `@public`/`@internal` annotations.
  </Card>
</CardGroup>

**Additional features:**

* **TS namespace declaration member detection**: New in v6, detects unused members in TypeScript `namespace` declarations (not `import * as ns`, fallow already handles that via namespace import narrowing).

## When to choose fallow

<CardGroup cols={2}>
  <Card title="Speed matters" icon="gauge-high">
    Large codebases where sub-second analysis enables watch mode and tight CI feedback loops.
  </Card>

  <Card title="CI pipelines" icon="circle-check">
    SARIF for GitHub Code Scanning, baselines for incremental adoption, `--changed-since` for PR-scoped checks.
  </Card>

  <Card title="Dead code + duplication" icon="layer-group">
    Replace both knip and jscpd with a single tool. Cross-reference dead code with duplication for prioritized cleanup.
  </Card>

  <Card title="Gradual adoption" icon="stairs">
    Per-issue severity rules (`error`/`warn`/`off`) and inline suppression comments let teams adopt incrementally.
  </Card>

  <Card title="AI-assisted development" icon="robot">
    Your team uses AI coding agents. Fallow provides `--format json` for CLI, an MCP server for typed tool calling, and `--changed-since` for PR-scoped checks.
  </Card>
</CardGroup>

## When to choose knip

<CardGroup cols={2}>
  <Card title="Niche plugins" icon="puzzle-piece">
    Your project depends on a specific tool that only knip has a plugin for, and a custom plugin isn't worth the effort.
  </Card>

  <Card title="Already working well" icon="thumbs-up">
    Knip is already integrated and performance isn't a pain point. No reason to migrate for the sake of it.
  </Card>

  <Card title="Custom reporters" icon="code">
    You need fully custom output formatting via JavaScript reporter functions.
  </Card>
</CardGroup>

## Summary table

|                                                       | fallow                              | knip                 |
| :---------------------------------------------------- | :---------------------------------- | :------------------- |
| Language                                              | Rust                                | Node.js (TypeScript) |
| Parser                                                | Oxc (native)                        | Oxc (NAPI bindings)  |
| Speed vs knip v6                                      | **2-13x faster** on common cases    | Baseline             |
| Parallelism                                           | Multi-core (rayon)                  | Single-threaded      |
| Dead code issue types                                 | 12                                  | 10                   |
| Code duplication                                      | Built-in                            | Not included         |
| Complexity and health score                           | Built-in (`fallow health`)          | No                   |
| Architecture boundaries                               | Yes                                 | No                   |
| Feature flag detection                                | Yes (`fallow flags`)                | No                   |
| Combined audit verdict                                | Yes (`fallow audit`)                | No                   |
| Plugins                                               | 94                                  | 147                  |
| Custom plugins                                        | JSONC/JSON/TOML                     | JavaScript           |
| SARIF output                                          | Yes                                 | No                   |
| Baseline comparison                                   | Yes (per-analysis)                  | No                   |
| Inline suppression                                    | Yes                                 | No                   |
| Git-aware (`--changed-since`, `--changed-workspaces`) | Yes                                 | Partial              |
| CODEOWNERS grouping                                   | Yes (`--group-by owner`, `section`) | Yes (reporter)       |
| Workspace filtering (globs, negation)                 | Yes                                 | Yes                  |
| Circular dependencies                                 | Yes                                 | Yes                  |
| Auto-fix                                              | Yes                                 | Yes                  |
| Config formats                                        | JSONC, JSON, TOML                   | JSON, TS             |
| Runtime dependency                                    | None (standalone binary)            | Node.js              |
| MCP server                                            | Built-in (`fallow-mcp`)             | No                   |

## Migrating from knip?

If you're coming from knip, fallow has a one-command migration path that automatically translates your configuration.

<CardGroup cols={2}>
  <Card title="Migrate from knip" icon="right-left" href="/migration/from-knip">
    Automatic config migration with `fallow migrate`.
  </Card>

  <Card title="Quick Start" icon="rocket" href="/quickstart">
    Get started with fallow in 2 minutes.
  </Card>
</CardGroup>
