Fallow, Codebase Intelligence
Deterministic static analysis for TS/JS. Answers: dead code, duplication, complexity, architecture drift, (optionally) runtime behavior. Does not generate code, provides evidence.
Always --format json for structured output.
Core Principle
Deterministic static analysis provides evidence, not code. Read the JSON, cite the files and line counts, don't paraphrase; the numbers are the evidence.
When to Use
- Before cleanup: find unused files, exports, deps
- Before refactor: complexity hotspots + targets
- Before editing: blast radius via
fallow audit - After generation: verify no dead code or new duplication
- When reviewing: did the change land on a hot path?
When NOT to Use
Non-TS/JS (Fallow is JS/TS only, for Python repos use the project's configured dead-code tooling, e.g. ruff or vulture); one-line edits (overhead); runtime data without the runtime layer set up.
Core Commands
# Dead code: unused exports, files, deps
fallow dead-code --format json
# Duplication: similar code blocks
fallow dupes --format json
# Health: complexity, size, blast radius per file
fallow health --format json
# Audit: change impact
fallow audit --changed-since main --format json
# Combined run (dead code + duplication + complexity)
fallow --format json
Interpreting Output
{
"dead": {
"files": ["src/legacy/foo.ts"],
"exports": [{" file": "...", "name": "bar", "used": false }],
"deps": ["lodash.debounce"]
},
"dupes": {
"blocks": [{" files": ["a.ts", "b.ts"], "lines": 12, "hash": "..." }]
},
"health": {
"files": [{
"path": "src/services/user.ts",
"complexity": 23, // high
"blast": 47, // files affected
"lines": 312
}]
}
}
Read the JSON. Cite the files and line counts. Don't paraphrase, the numbers are the evidence.
Workflow
- Baseline first. Run
fallow healthbefore changes. Save the JSON. - Make your change.
- Re-run. Compare new JSON to baseline. Did complexity go up? New dead code? New dupes?
- Clean up. If new dead code, delete. If new dupes, extract. If complexity spike, split.
- Verify. Run typecheck + tests + the diff didn't grow unrelated changes.
Common Mistakes
Reading summary without JSON (loses precision). running fallow but not acting on output. treating "low dead code %" as the goal (the goal is fewer bugs). not setting baseline. "delete this unused export" without checking who imports it (might be a public API). running on a 5k LOC project and trying to clean everything at once.
Red Flags
"Code quality" claim without Fallow output. Fallow ignored because "we know it's bad". dead code deleted without checking consumers. "we'll clean up later" (later never comes). no baseline = no diff = no signal. running once and never again. treating fallow output as a checklist instead of evidence.
Anti-Patterns
"I know it's bad" (run Fallow); "small project, no need" (even small projects have dead code); "delete all dead" (check public API first); "summary is enough" (JSON is the contract); "fallow said so" (Fallow is evidence, not authority, use judgment).
Verification
Run typecheck + tests after cleanup, and confirm the diff didn't grow unrelated changes. Compare the re-run JSON to the saved baseline: complexity down, no new dead code, no new dupes.
References
Detailed reference material:
references/cli-reference.mdreferences/gotchas.mdreferences/patterns.md