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.
Recommended workflow
Preview changes
Run a dry run to see exactly what would be removed without making any changes.
$ fallow fix --dry-run
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.
Apply fixes
After reviewing the preview, apply the changes. In interactive terminals, fallow asks for confirmation before writing.In CI or non-TTY environments, use
--yes to skip confirmation: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.What gets fixed
- Unused exports: the
exportkeyword is removed, keeping the declaration. For exported enums where the enum itself is never referenced outside its body in the file, the entireenumblock is deleted. - Unused dependencies: removed from
package.jsonwhen 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.yamlby 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 withfix.catalog.deletePrecedingComments("auto","always", or"never"). Two escape hatches keep curated comments safe regardless of policy: a# fallow-keepmarker on any line in the block preserves it, and theautopolicy 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 tocatalog: {}(or<name>: {}) instead of leaving barecatalog:, because pnpm rejects null-valued catalogs withCannot convert undefined or null to objectat install time. Entries whosehardcoded_consumersis non-empty (a workspace package still pins a hardcoded version of the same package, where removing the catalog entry would breakpnpm 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 runpnpm installsopnpm-lock.yamlstays in sync.
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):trueonly when the finding’shardcoded_consumersarray is empty. When a workspace package still pins a hardcoded version of the same package,fallow fixskips the entry to avoid breakingpnpm install, and the action is emitted withauto_fixable: false.remove-dependencyvsmove-dependency(dependency findings): when the finding’sused_in_workspacesarray is non-empty, the primary action flips tomove-dependencywithauto_fixable: falsebecausefallow fixwill not remove a dependency that another workspace imports. On findings without cross-workspace consumers the action staysremove-dependencywithauto_fixable: true.add-to-configforignoreExports(duplicate-exports):truewhenfallow fixcan 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.jsonusing the same scaffoldingfallow initemits and layers the new rules on top.falseinside 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-configtofallow fixfrom pre-commit hooks, CI bots, andfallow watchto opt out of the create-fallback; the action then surfaces withauto_fixable: falseand is skipped at apply time.update-catalog-reference(unresolved-catalog-references): alwaysfalsetoday. The catalog-switching applier is not yet wired; the field is non-singleton so future enablement does not require a schema change.
suppress-line and suppress-file actions are uniformly auto_fixable: false.
JSON output
For scripting, CI, and agent workflows:See also
CLI: fix
Full reference for the
fallow fix command and its flags.Dead Code Analysis
Understand what fallow detects before auto-fixing.