Skip to main content
fallow fix removes unused exports and unused dependencies from your codebase. In agent workflows, fallow fix --yes --format json cleans up dead code non-interactively after code generation.
Always commit your changes before running fallow fix. Git lets you undo if needed.
1

Preview changes

Run a dry run to see exactly what would be removed without making any changes.
fallow fix --dry-run
$ fallow fix --dry-run
Would remove export from src/components/Card/index.ts:1 `CardFooter`
Would remove export from src/providers/trpc-provider/index.tsx:12 `TRPCProvider`
Would remove export from src/server/jobs/queue.ts:61 `enqueueJobDelayed`
Would remove export from src/server/jobs/queue.ts:206 `sweepStuckProcessingJobs`
Would remove export from src/server/jobs/queue.ts:276 `getDeadLetterJobs`
Would remove `@trpc/react-query` from dependencies

6 fixes available (5 exports, 1 dependency). Run without --dry-run to apply.
2

Review the output

Check that every proposed removal is safe. Pay attention to exports consumed by external packages or dynamic imports that fallow can’t detect statically.
fallow fix --dry-run --format json
3

Apply fixes

After reviewing the preview, apply the changes. In interactive terminals, fallow asks for confirmation before writing.
fallow fix
In CI or non-TTY environments, use --yes to skip confirmation:
fallow fix --yes
Agents typically use fallow fix --yes --format json to apply fixes non-interactively. The JSON output confirms exactly what was changed, so the agent can verify the result.
4

Verify the result

Run your build and tests to confirm nothing broke.
npm run build && npm test

What gets fixed

  • Unused exports: the export keyword is removed, keeping the declaration. For exported enums where the enum itself is never referenced outside its body in the file, the entire enum block is deleted.
  • Unused dependencies: removed from package.json when they are not imported by another workspace
  • Unused enum members: removed from the enum declaration. When every member of an exported enum is unused, the whole declaration is deleted in one pass instead of leaving behind an empty export enum X {} shell. Importers in other files now reference a name that no longer exists, so run your TypeScript build to find and clean them up.
  • Unused pnpm catalog entries: removed from pnpm-workspace.yaml by line-aware deletion. Object-form entries are removed as one block. By default, fallow also removes a contiguous YAML comment block immediately above the entry when it clearly belongs to that entry; configure this with fix.catalog.deletePrecedingComments ("auto", "always", or "never"). Two escape hatches keep curated comments safe regardless of policy: a # fallow-keep marker on any line in the block preserves it, and the auto policy additionally preserves section-banner blocks whose body starts with three or more =, -, *, _, ~, +, or # characters (e.g. # === React 18 production pins ===). Other comments and stylistic choices in the file are preserved. When the last entry of a catalog group is removed, the header is rewritten to catalog: {} (or <name>: {}) instead of leaving bare catalog:, because pnpm rejects null-valued catalogs with Cannot convert undefined or null to object at install time. Entries whose hardcoded_consumers is non-empty (a workspace package still pins a hardcoded version of the same package, where removing the catalog entry would break pnpm install) are skipped; the skip is reported in the fix output so you can migrate the consumer first and rerun. After a successful catalog edit fallow reminds you to run pnpm install so pnpm-lock.yaml stays in sync.
Auto-fix does not delete entire files or remove unused class members. Use fallow dead-code to find those and remove them manually.

auto_fixable is per-finding, not per action type

Every action in a finding’s actions[] array carries an auto_fixable bool. The value is evaluated per finding, not per action type: the same action type may appear with auto_fixable: true on one finding and auto_fixable: false on another, depending on per-instance guards in the fallow fix applier. Agents that filter on auto_fixable: true to decide what is safe to apply blindly must branch on the bool of each individual action, not on the action type alone. Per-instance flips today:
  • remove-catalog-entry (unused-catalog-entries): true only when the finding’s hardcoded_consumers array is empty. When a workspace package still pins a hardcoded version of the same package, fallow fix skips the entry to avoid breaking pnpm install, and the action is emitted with auto_fixable: false.
  • remove-dependency vs move-dependency (dependency findings): when the finding’s used_in_workspaces array is non-empty, the primary action flips to move-dependency with auto_fixable: false because fallow fix will not remove a dependency that another workspace imports. On findings without cross-workspace consumers the action stays remove-dependency with auto_fixable: true.
  • add-to-config for ignoreExports (duplicate-exports): true when fallow fix can safely apply the action, which today means EITHER a fallow config file already exists OR no config exists and the working directory is NOT inside a monorepo subpackage. In the second case the applier creates .fallowrc.json using the same scaffolding fallow init emits and layers the new rules on top. false inside a monorepo subpackage with no workspace-root config, because the applier refuses to fragment per-package configs across the monorepo and points at the workspace root instead. Pass --no-create-config to fallow fix from pre-commit hooks, CI bots, and fallow watch to opt out of the create-fallback; the action then surfaces with auto_fixable: false and is skipped at apply time.
  • update-catalog-reference (unresolved-catalog-references): always false today. The catalog-switching applier is not yet wired; the field is non-singleton so future enablement does not require a schema change.
All suppress-line and suppress-file actions are uniformly auto_fixable: false.

JSON output

For scripting, CI, and agent workflows:
fallow fix --dry-run --format json
{
  "changes": [
    {
      "type": "remove-export",
      "file": "src/components/Card/index.ts",
      "symbol": "CardFooter",
      "line": 1
    },
    {
      "type": "remove-export",
      "file": "src/providers/trpc-provider/index.tsx",
      "symbol": "TRPCProvider",
      "line": 12
    },
    {
      "type": "remove-export",
      "file": "src/server/jobs/queue.ts",
      "symbol": "enqueueJobDelayed",
      "line": 61
    },
    {
      "type": "remove-export",
      "file": "src/server/jobs/queue.ts",
      "symbol": "sweepStuckProcessingJobs",
      "line": 206
    },
    {
      "type": "remove-export",
      "file": "src/server/jobs/queue.ts",
      "symbol": "getDeadLetterJobs",
      "line": 276
    },
    {
      "type": "remove-dependency",
      "package": "@trpc/react-query"
    }
  ],
  "summary": {
    "total_changes": 6,
    "exports_removed": 5,
    "dependencies_removed": 1
  }
}

See also

CLI: fix

Full reference for the fallow fix command and its flags.

Dead Code Analysis

Understand what fallow detects before auto-fixing.