Global flags

These flags are shared across fallow commands. Some commands reject flags that are not meaningful for that surface.

Reference

The --dupes-* flags apply to combined mode, fall back to the config value when unset, and mirror the standalone fallow dupes flag of the same name.

FlagDescription
-r, --root <PATH>Project root directory (default: current working directory)
-c, --config <PATH>Path to config file (default: auto-detected)
-f, --format <FORMAT>Output format: human (default), json, sarif, compact, markdown, codeclimate, gitlab-codequality, pr-comment-github, pr-comment-gitlab, review-github, review-gitlab, badge. Alias: --output. --format json is compact by default; add --pretty for indented output.
--prettyIndent --format json output for manual inspection. JSON is compact by default so machine and agent consumers get the same schema with less output; this flag restores human-readable indentation. Applies only to JSON output. SARIF, Code Climate, baselines, snapshots, caches, and other persisted JSON keep their existing presentation regardless of this flag.
-q, --quietSuppress progress bars and status messages
--no-cacheDisable incremental caching (force full re-parse)
--threads <N>Number of parser threads (default: available parallelism)
--max-file-size <MB>Skip source files larger than this many megabytes at discovery instead of parsing them (default 5; 0 disables the guard). Guards against the out-of-memory blowup a single multi-megabyte generated, vendored, or bundled file causes on large repositories, and also skips large one-line minified JS assets while the guard is enabled. Declaration files (.d.ts) are always analyzed regardless of size. Skipped files are reported on stderr and in --format json under workspace_diagnostics (kind: "skipped-large-file" or "skipped-minified-file"). Also settable via FALLOW_MAX_FILE_SIZE.
--changed-since <REF> (alias: --base)Only report issues in files changed since this git ref
--diff-file <PATH>Path to a unified diff (e.g. git diff --unified=0 main...HEAD) used to narrow source-anchored findings to lines inside an added hunk. Point findings (unused-export, unresolved-import, boundary-violation, etc.) drop when their source line is not in the diff; range findings (complexity hotspots, clone families) drop when their [start_line, end_line] does not overlap the diff. Project-level findings (unused deps, catalog entries, dependency overrides) bypass the analysis filter because they anchor at fixed package.json / pnpm-workspace.yaml lines a PR rarely touches even when it semantically caused them. Sticky PR/MR summaries can set FALLOW_SUMMARY_SCOPE=diff to filter those project-level findings too. Also drives line-level scoping of the runtime-coverage hot-path-touched verdict. Pass - as the path or use --diff-stdin to read the diff from stdin (gh pr diff | fallow audit --diff-file -). When combined with --changed-since, the diff filter wins for line-level filtering and --changed-since still scopes file discovery; a one-line stderr note records the precedence. Falls back to the FALLOW_DIFF_FILE env var when omitted.
--diff-stdinRead the unified diff from stdin instead of a file. Equivalent to --diff-file -. Mutually exclusive with a non-stdin --diff-file PATH value. Useful for piping gh pr diff or git diff directly into fallow.
--churn-file <PATH>Import change history from a fallow-churn/v1 JSON file instead of git log, for projects with no git repository. Affects the churn-backed health signals only. See fallow health › Importing churn from a non-git VCS.
--baseline <PATH>Compare against a previously saved baseline file
--save-baseline <PATH>Save the current results as a baseline file
--fail-on-regressionFail if issue count increased beyond tolerance vs a regression baseline
--tolerance <N>Allowed increase: "2%" (percentage) or "5" (absolute). Default: "0"
--regression-baseline <PATH>Path to regression baseline file (default: .fallow/regression-baseline.json)
--save-regression-baseline <PATH>Save current issue counts as a regression baseline
--productionProduction mode: exclude test/story/dev files, only start/build scripts
--no-productionForce production mode off for every analysis, overriding a project config's production: true. Conflicts with --production.
--production-dead-codePer-analysis production mode for dead-code in bare combined runs and fallow audit. See Per-analysis production mode.
--production-healthPer-analysis production mode for health in bare combined runs and fallow audit.
--production-dupesPer-analysis production mode for duplication in bare combined runs and fallow audit.
-w, --workspace <PATTERNS>Scope output to one or more workspaces. Accepts exact names, globs matched against both the package name AND the workspace path (apps/*, @scope/*), and !-prefixed negations (!apps/legacy). Values can be comma-separated (-w web,admin) or the flag can be repeated. Quote patterns containing ! or glob chars to avoid shell expansion.
--changed-workspaces <REF>Git-derived monorepo CI scoping: scope output to workspaces containing any file changed since REF (e.g. origin/main, HEAD~1). Auto-derives the workspace set from git diff so CI jobs don't hand-maintain a --workspace list. Mutually exclusive with --workspace. A missing ref or non-git directory is a hard error (exit 2), not a silent full-scope fallback. Root-only diffs map to 0 workspaces and exit 0 with no issues.
--performanceShow pipeline timing breakdown
--explainIn human format, prints a Description: line under each section header. In JSON format, includes metric definitions in the output _meta object. Always enabled for MCP.
--ciCI mode: equivalent to --format sarif --fail-on-issues --quiet
--fail-on-issuesExit with code 1 if issues are found
--sarif-file <PATH>Write SARIF output to a file (in addition to the primary --format output)
-o, --output-file <PATH>Write the report to a file instead of stdout, for any --format (no ANSI codes). Useful on large projects where the terminal scrollback truncates the top. Progress and a Report written to <path> confirmation stay on stderr (suppressed by --quiet). Valid with dead-code, dupes, health, security, and bare invocation; composes with --sarif-file.
--report-path-prefix <PREFIX>Override the repository-root offset prepended to every path in the CI-facing formats; an empty string disables rebasing. See Repository-root paths in CI formats.
--group-by <MODE>Group output by CODEOWNERS ownership (owner), first directory component (directory), workspace package (package), or GitLab CODEOWNERS section (section). When active, all output formats partition issues into labeled groups.
--summaryPrint a one-line summary of issue counts at the end of the run. In JSON format, adds a summary counts object to the output.
--only <check,dupes,health>Run only specific analyses when no subcommand is given
--skip <check,dupes,health>Skip specific analyses when no subcommand is given
--coverage <PATH>Feed Istanbul coverage data to the embedded health analysis in combined mode. Same fallback chain as fallow health --coverage.
--coverage-root <PATH>Absolute prefix to strip from Istanbul coverage paths in combined mode. See fallow health --coverage-root.
--dupes-mode <MODE>Override duplicate detection mode.
--dupes-nearInclude function-scoped near-miss clones.
--dupes-threshold <PCT>Override the duplication percentage failure threshold.
--dupes-min-tokens <N>Override the minimum token count for clone detection.
--dupes-min-lines <N>Override the minimum line count for clone detection.
--dupes-min-occurrences <N>Override the minimum clone occurrences (must be >= 2).
--dupes-skip-localOnly report cross-directory duplicates.
--dupes-cross-languageEnable TypeScript to JavaScript duplicate matching.
--dupes-ignore-importsExclude module wiring from duplicate detection (default).
--dupes-no-ignore-importsCount module wiring as clone candidates. Conflicts with --dupes-ignore-imports.
--scoreCompute health score (0-100 with letter grade) in combined mode. Enables the health delta header in PR comments. Also available on fallow health.
--trendCompare current health metrics against the most recent saved snapshot. Implies --score. Also available on fallow health.
--save-snapshot [PATH]Save a vital signs snapshot for trend tracking. Default path: .fallow/snapshots/<timestamp>.json. Forces file-scores and hotspot computation. Also available on fallow health.
--include-entry-exportsReport unused exports in entry files instead of auto-marking them as used. Catches typos in framework exports (e.g. meatdata instead of metadata). Also configurable via includeEntryExports: true in your fallow config; the CLI flag wins when set.

Repository-root paths in CI formats

CI platforms resolve file paths against the repository root: GitHub annotations, CodeClimate reports in GitLab, and inline review comments all reject or misplace paths relative to anything else. When --root points at a subdirectory of a git repository (a monorepo package like packages/app/), the CI-facing formats (github-annotations, github-summary, codeclimate, review-github, review-gitlab) therefore emit repository-root-relative paths: fallow detects the offset between --root and the git toplevel and prepends it automatically. --report-path-prefix overrides the detected offset for containerized or vendored checkouts where the git toplevel does not match the CI workspace; an empty string (--report-path-prefix '') disables rebasing entirely and restores --root-relative paths.

Supplied diffs (--diff-file, --diff-stdin, FALLOW_DIFF_FILE) get the same treatment in reverse: fallow detects whether the diff's paths are repository-root-relative or --root-relative and filters findings accordingly. A diff that parses but touches no analyzable files (deletion-only, binary-only, or empty) filters the report to zero findings; only a diff whose paths cannot be placed at all falls back to the full-scope report, with a warning saying so.

Loaded config disclosure

When fallow loads a config file (either auto-discovered or via --config), it prints a single line to stderr:

loaded config: /repo/.fallowrc.json

This shows which .fallowrc.json is in effect in monorepos where multiple configs exist. The line is suppressed when:

  • --quiet is set
  • --format is anything other than human (json, sarif, compact, markdown, codeclimate, gitlab-codequality, pr-comment-github, pr-comment-gitlab, review-github, review-gitlab, badge)

For deeper inspection (the resolved config with extends merged), use the dedicated fallow config subcommand.

Examples

# Analyze a project in a different directory
fallow dead-code -r /path/to/project

# Use a specific config file
fallow dead-code -c configs/fallow-strict.json

# JSON output with no progress messages
fallow dead-code -f json --quiet

# Limit parallelism to 4 threads
fallow dead-code --threads 4

# Scope to a single workspace package
fallow dead-code -w @myorg/ui

# Scope to whichever workspaces changed since origin/main (CI primitive)
fallow --changed-workspaces origin/main

# Show timing breakdown
fallow dead-code --performance

# Group issues by CODEOWNERS ownership (see Grouped output below)
fallow dead-code --group-by owner

# Health score in combined mode
fallow --score

# Save a snapshot and track trends
fallow --save-snapshot
fallow --trend

Per-analysis production mode

Bare combined runs (fallow with no subcommand) and fallow audit accept three per-analysis production flags so you can enable production mode for one analysis without forcing it on the others:

# Treat health as production-only, leave dead-code and dupes in full-tree mode
fallow --production-health

# Audit changed files with production-only health
fallow audit --base main --production-health

The matching environment variables FALLOW_PRODUCTION_DEAD_CODE, FALLOW_PRODUCTION_HEALTH, and FALLOW_PRODUCTION_DUPES accept the same set of values as FALLOW_PRODUCTION (true, false, 1, 0, yes, no, on, off). The production config field also accepts a per-analysis object:

{
  "production": {
    "deadCode": false,
    "health": true,
    "dupes": false
  }
}

Precedence (highest to lowest): CLI flags (--production, --production-{dead-code,health,dupes}), per-analysis env var (FALLOW_PRODUCTION_HEALTH, etc.), global env var (FALLOW_PRODUCTION), config (production: { ... } or production: true). The legacy boolean form (--production, production: true, FALLOW_PRODUCTION=true) is unchanged and still applies to every analysis.

The per-analysis CLI flags are rejected when used with a subcommand other than audit (e.g. fallow dead-code --production-health errors). Use the bare command or the per-analysis env vars in that case.

Grouped output

The --group-by flag partitions all issues into labeled groups. This works with every output format and every subcommand.

ModeGroupingRequires
ownerCODEOWNERS file ownership. Auto-probes CODEOWNERS, .github/CODEOWNERS, .gitlab/CODEOWNERS, docs/CODEOWNERS. First owner on multi-owner lines wins.A CODEOWNERS file (or set codeowners in config)
directoryFirst path component (e.g. src/utils/foo.ts groups under src)Nothing
packageWorkspace package name (e.g. @myorg/ui). Issues are grouped by the package they belong to.A monorepo with workspace packages
sectionGitLab CODEOWNERS [Section] header name. Distinct sections stay in distinct groups even when they share a default reviewer, so teams with one shared lead reviewer across many sections get per-section triage instead of one giant bucket.A GitLab-style CODEOWNERS file with at least one [Section] header

With --format json, the output shape changes to a grouped envelope:

{
  "kind": "dead-code-grouped",
  "grouped_by": "owner",
  "total_issues": 12,
  "groups": [
    { "key": "@frontend-team", "total_issues": 8, "unused_files": [], "unused_exports": [] },
    { "key": "@backend-team", "total_issues": 4, "unused_exports": [] }
  ]
}

For --group-by section, each group also carries an owners array with the section's default owners:

{
  "kind": "dead-code-grouped",
  "grouped_by": "section",
  "total_issues": 6,
  "groups": [
    {
      "key": "billing",
      "owners": ["@core-reviewers", "@alice", "@bob"],
      "total_issues": 2,
      "unused_exports": []
    },
    {
      "key": "notifications",
      "owners": ["@core-reviewers", "@alice", "@bob"],
      "total_issues": 1,
      "unused_exports": []
    }
  ]
}

Section and owner groups are not interchangeable: owner collapses all sections that share a lead reviewer into a single bucket, while section preserves the [Section] headers as stable group keys across reviewer rotation.

Set a custom CODEOWNERS path via the codeowners field in .fallowrc.json if your file isn't in a standard location.

Incremental caching

Fallow caches parsed file data between runs to skip unchanged files. On the second run, only modified files are re-parsed. The rest are loaded from cache.

How it works:

  1. Each file is hashed with xxh3 (extremely fast, non-cryptographic)
  2. If the hash matches the cached version, parsing is skipped entirely
  3. The module graph is rebuilt from cached + freshly-parsed data

Use --performance to see cache hit rates and per-stage timings. This is helpful for diagnosing slow runs.

fallow dead-code --performance
 Discovery     12ms   (142 files)
 Parsing       48ms   (23 parsed, 119 cached)
 Resolution    15ms
 Analysis       8ms
 Total         83ms

Use --no-cache to force a full re-parse. This is useful after major refactors or when debugging unexpected results.

fallow dead-code --no-cache

Set cache.dir in the project config or FALLOW_CACHE_DIR in the environment to move the persistent cache out of .fallow/cache.bin. The env var wins when both are present.

FALLOW_CACHE_DIR=/tmp/fallow-cache fallow dead-code

See also