Fallow is codebase intelligence for TypeScript and JavaScript. The free static layer finds unused files, exports, dependencies, types, enum members, class members, unresolved imports, unlisted deps, duplicate exports, circular dependencies, boundary violations, code duplication, and complexity hotspots, plus opt-in API hygiene checks such as private type leaks. A paid runtime intelligence layer (Fallow Runtime) adds production execution evidence (hot and cold paths, runtime-backed review, runtime-weighted health, stale-flag evidence, trends, alerts). Rust alternative to knip built on the Oxc parser ecosystem.
crates/
config/ -- Configuration types, custom framework presets, package.json parsing, workspace discovery
types/ -- Shared type definitions (discover, extract, results, suppress, serde_path)
extract/ -- AST extraction engine (visitor.rs, complexity.rs, sfc.rs, astro.rs, mdx.rs, css.rs, parse.rs, cache.rs, suppress.rs, tests/)
graph/ -- Module graph construction (graph/), import resolution (resolve.rs), project state (project.rs)
license/ -- Offline Ed25519 JWT verification for paid features (alg pinned, file+env load precedence, 7/30/hard-fail grace ladder)
v8-coverage/ -- V8 ScriptCoverage parser + byte-offset-to-line/col mapper + Istanbul normalizer (open-source layer of Phase-2 runtime coverage)
core/ -- Analysis orchestration: discovery, plugins, scripts, duplicates, cross-reference, caching, progress
analyze/ -- Dead code detection (mod.rs orchestration, predicates.rs, unused_files/exports/deps/members.rs)
plugins/ -- Plugin system + tooling.rs (general tooling dependency detection)
duplicates/ -- Clone detection (families, normalize, tokenize)
cli/ -- CLI binary, split into per-command modules
audit.rs, check.rs, dupes.rs, health/, watch.rs, fix/, init.rs, list.rs, schema.rs, validate.rs, regression/
license/ -- `fallow license {activate, status, refresh, deactivate}` with offline JWT verify plus live trial / refresh flows
coverage/ -- `fallow coverage setup` resumable first-run state machine for runtime coverage
report/ -- Output formatting (mod.rs dispatch, human/, json.rs, sarif.rs, compact.rs, markdown.rs)
migrate/ -- Config migration (mod.rs, knip.rs, jscpd.rs)
lsp/ -- LSP server, split into modules
main.rs, diagnostics/, code_actions/, code_lens.rs, hover.rs
mcp/ -- MCP server for AI agent integration (stdio transport, wraps CLI)
editors/
vscode/ -- VS Code extension (LSP client, tree views, status bar, auto-download)
npm/
fallow/ -- npm wrapper package with optionalDependencies pattern
action/ -- GitHub Action (composite)
jq/ -- jq scripts for summaries, annotations, review comments, merging
scripts/ -- Bash scripts (install, analyze, annotate, comment, review, summary)
tests/ -- Unit tests for jq scripts (run: bash action/tests/run.sh)
ci/ -- GitLab CI template and supporting scripts
jq/ -- jq scripts for GitLab MR formatting (comments, reviews, summaries, merging)
scripts/ -- Bash scripts (comment.sh, review.sh)
tests/ -- Unit tests for jq scripts (92 tests, run: bash ci/tests/run.sh)
tests/
fixtures/ -- Integration test fixtures
decisions/ -- Architecture Decision Records (ADRs)
Pipeline: Config → File Discovery → Incremental Parallel Parsing (rayon + oxc_parser + oxc_semantic, cache-aware) → Script Analysis → Module Resolution (oxc_resolver) → Graph Construction → Re-export Chain Resolution → Dead Code Detection → Reporting
git config core.hooksPath .githooks # Enable pre-commit hooks (fmt + clippy)
cargo build --workspace
cargo test --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --all -- --check
cargo run --bin fallow # Run all analyses (dead-code + dupes + health)
cargo run --bin fallow -- watch # Watch mode
cargo run --bin fallow -- fix --dry-run # Auto-fix preview- Config files:
.fallowrc.json>.fallowrc.jsonc>fallow.toml>.fallow.toml - No
detectsection in config; useruleswith"off"severity - No
outputin config; output format is CLI-only via--format - Rules severity:
error(fail CI, default) |warn(exit 0) |off(skip) - Inline suppression:
// fallow-ignore-next-line [issue-type]and// fallow-ignore-file [issue-type] - Environment variables:
FALLOW_FORMAT,FALLOW_QUIET,FALLOW_BIN(binary path for MCP) - See
.claude/rules/code-quality.mdfor clippy, size assertions, and CI hardening details
Documented as Architecture Decision Records in decisions/. Key decisions:
- No TypeScript compiler (ADR-001): Syntactic analysis via Oxc parser +
oxc_semantic. No type resolution, no tsc. - Flat edge storage (ADR-002): Contiguous
Vec<Edge>with range indices for cache-friendly traversal. - FxHashMap/FxHashSet required (ADR-003): Standard
HashMap/HashSetdisallowed (enforced via.clippy.toml). - Path-sorted FileIds (ADR-004): Stable cross-run identity, not insertion order.
- Re-export chain resolution (ADR-005): Iterative propagation through barrel files with cycle detection.
- Hidden directory allowlist (ADR-006):
.storybook,.vitepress,.well-known,.changeset,.githubtraversed; other dotdirs skipped.
- Conventional commits:
feat:,fix:,chore:,refactor:,test: - Signed commits (
git commit -S) - No AI attribution in commits
- Never reduce fallow to "dead code tool" in taglines or summaries; reference all 5 analysis areas (unused code, circular deps, duplication, complexity hotspots, boundary violations). Category is "codebase analyzer."
- Comparison pages must be research-backed with source links; never claim a competitor "can't" do something without checking
- Design specs are definitions, not implementations: tokens, rules, components, ASCII wireframes, table-described behavior; no CSS/JS/HTML code blocks
~/Sites/fallow-2/is a working copy of fallow main; primary checkout is the bare-config'd~/Sites/fallow/.internal/,quality/,reference/,benchmarks/fixtures/,benchmarks/knip6/are gitignored symlinks;.internal/points at~/Sites/fallow-cloud/.internal/(single source of truth, edit only there); the rest point at~/Sites/fallow/npm/fallow/skills/is a vendored copy of~/Sites/fallow-skills/; refresh happens at release time, not manually- Edit fallow skills in
~/Sites/fallow-skills/fallow/skills/fallow/, never in the symlinked~/.agents/skills/fallow/ - GitHub org:
fallow-rs/fallow(usegh ... --repo fallow-rs/fallow); neverbartwaardenburg/fallow fallow checkis dead-code only; barefallowruns the full pipeline (dead-code + dupes + health)
Multiple agents and background sessions frequently land commits in fallow main concurrently. Treat every working tree as racy:
- Commit WIP early. If a feature takes more than ~10 minutes and parallel sessions are active, switch to a feature branch (
git checkout -b feat/<name>) and commit per chunk. Uncommitted state in main does not survive even one parallelgit stashcycle, especially for untracked files. - Verify commit authors before every push. Run
git log --format="%H %ae %s" <base>..HEADand abort if any author is notbart@waardenburg.dev, a contributor email, or...@users.noreply.github.com. Worktrees and pre-push hooks have leakedtest@example.comandtest@test.comcommits in the past. - Never push fallow commits via fallow-2 (or any worktree) when WIP exists. Fix the bare-repo push at its root (e.g. unset
GIT_DIR/GIT_WORK_TREEin.githooks/pre-push) or create a fresh ephemeral worktree withgit -C <bare> worktree add /tmp/fallow-push <branch>. combined.rsis a merge-conflict magnet. It absorbs orientation header, nudge, entry-point display, summary threading, baseline deltas, health options. Assign ALLcombined.rsedits to a single agent that runs after parallel crate-level work finishes.- After cherry-picking from worktree agents, always run
cargo fmt --all. Worktree agents do not always produce rustfmt-compliant code. - After every worktree merge, scan for orphan conflict markers.
grep -r '<<<<<<' crates/(already auto-enforced by the conflict-marker-scan PostToolUse hook, but run manually before pushing). - After cleaning up worktrees, force-remove all of them and
cargo clean -p <crate>before testing. Stale worktree compilation artifacts make new code invisible tocargo test --list. - Worktree agents may skip commits. After each worktree agent completes, verify with
git log <base>..<branch> --oneline; if empty, check for unstaged changes in the worktree directory and commit manually before cleanup.
See AGENTS.md for AI agent integration guide.