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
1
Preview changes
Run a dry run to see exactly what would be removed without making any changes.
$ fallow fix --dry-run
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.
3
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.4
Verify the result
Run your build and tests to confirm nothing broke.
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.