Fallow: Rust-Powered Static Analysis Detects Dead Code & Architecture Issues in TypeScript Projects
Fallow is a Rust-based static analysis tool that builds a complete dependency graph of TypeScript and JavaScript projects to detect dead code, circular dependencies, code duplication, complexity hotspots, architecture violations, and style drift, offering zero-configuration setup, millisecond-speed scans, CI integration, and machine-readable output for AI coding assistants.
What Problem Does It Solve
Every long-lived codebase accumulates "dead code" — code that no one dares delete because it's unclear whether anything still uses it. A utility function might be called in three places, or it might have zero references, but proving a negative (that something is not used) is far harder than proving a positive. Traditional approaches fall short:
Manual inspection doesn't scale beyond a few hundred files; no single developer holds the full project map in memory.
Test coverage only shows which paths tests execute, not which paths run in production. Code covered by tests but never called in production still shows as green.
Linters like ESLint excel at syntax and style rules but lack the global dependency graph needed to answer cross-file questions like "Is this export ever imported?"
Fallow's solution is straightforward: build the complete dependency graph and query it. It treats every file as a node and every import statement as an edge. Once the graph exists, nodes with no incoming edges (dead files), exports with no references (dead exports), and cycles (circular dependencies) become trivial graph queries. A real-world audit of the vitest repository — analyzing 19 files changed across the last 15 commits — reported 156 dead-code issues, 6 complexity findings, and 8 duplicate-code groups in just 1.05 seconds.
How It Works
Fallow's pipeline has three stages, each operating on the unified dependency graph:
1. Graph Construction
The scanner walks the entire codebase, extracting file-to-file import relationships and style-token usage relationships into a single graph. This graph is the foundation for all subsequent checks.
2. Graph-Based Analyses
Dead-code detection : Finds files, exports, types, enum members, class members, and npm dependencies that no entry point reaches. It also handles circular dependencies — mutual imports or re-export loops that create cycles in the graph, a classic sign of architectural decay.
Duplicate-code detection : Uses a suffix-array algorithm to locate copy-pasted fragments across JavaScript, TypeScript, CSS, and CSS-in-JS, including inside Vue, Svelte, and Astro component blocks.
Complexity detection : Scores each module's complexity, surfaces hotspots, and assigns the whole codebase a 0–100 health score with a letter grade.
Architecture-boundary validation : Ships with four built-in layer presets — bulletproof, layered, hexagonal, and feature-sliced — to verify that code respects its assigned architectural layers.
Style-drift detection : For CSS and CSS-in-JS, checks whether design-system tokens are being used incorrectly.
3. Output
Results are emitted in over a dozen formats: human-readable terminal report, JSON, SARIF, Markdown, CodeClimate, GitHub annotations, and CI pull-request comments. Exit codes are explicit: 0 = clean, 1 = findings (normal), 2 = genuine error.
A clever architectural split separates static analysis (free, open-source, runs without executing code) from an optional paid layer called Fallow Runtime . The static layer produces "candidates" — code that might be unused. The runtime layer merges real production execution evidence (e.g., V8 coverage dumps) to confirm which candidates are truly dead. This "static candidates + runtime confirmation" model directly addresses the coverage-tool gap where tested-but-never-used code appears green.
Getting Started
Fallow emphasizes zero-config adoption. It bundles over 100 framework plugins that auto-detect entry points and framework-consumed exports, so the first run usually requires no configuration. npx fallow Runs the full suite (dead code, duplication, health score). For incremental checks on a pull request's changed files: npx fallow audit To install as a dev dependency: npm install --save-dev fallow For onboarding onto a legacy codebase, npx fallow recommend performs a read-only scan, detects frameworks, build tools, and package managers, prints a starter config file, and leaves subjective choices to the user. TypeScript projects can opt into a slower but more precise --type-aware mode.
CI integration is provided via a ready-made GitHub Action that defaults to blocking on new findings in changed files. Teams can start in "report-only" mode and tighten the gate later.
Note : Fallow targets the JavaScript/TypeScript ecosystem. Pure Python, Go, or other non-JS/TS projects are not supported.
Comparison with Similar Tools
knip : Specializes in unused files/exports — closest to Fallow's dead-code module. Benchmarks show Fallow faster on fastify (64 ms vs 205 ms) and preact (74 ms vs 2.01 s, ~27×), but the README honestly notes knip wins on astro and TypeScript projects, and jscpd remains faster for raw duplicate scanning. Performance is trade-off dependent, not a clean sweep.
jscpd : Veteran duplicate-code detector; still fastest for pure duplication scanning. Fold's duplication check is one of many features.
stylelint : Enforces style rules; Fallow's style-drift analysis tackles a higher-level problem — whether design-system tokens are misused. Complementary, not overlapping.
ESLint / Oxlint / tsc --noEmit : Handle syntax, style, and type-checking locally. Fallow addresses cross-file structural issues. The project explicitly states it does not replace these tools.
A differentiating advantage is first-class support for AI coding agents. Fallow defines a stable JSON output contract, explicit exit codes, and an MCP server so assistants like Claude Code and Codex can invoke analysis, audit, and fix-preview programmatically. As AI generates bulk code changes, a machine-verifiable quality gate becomes essential.
Who Should Use It
Frontend / full-stack developers maintaining TS/JS projects who want to clean accumulated dead code without guesswork; audit gates prevent regressions.
Architects / tech leads monitoring circular dependencies, layer violations, and runaway complexity; the health score and layer presets provide quantifiable guardrails.
CI maintainers seeking a lightweight, progressive quality gate — GitHub Action works out of the box, with a smooth path from "report only" to "block on new issues."
Developers using AI coding tools who need fast, machine-readable verification that AI-generated code hasn't introduced dead code or broken dependency structure.
Not a fit: non-JS/TS projects, or tiny throwaway projects with no legacy burden.
Key Takeaways (Even If You Don't Adopt Fallow)
Prove negatives by making structure explicit. Deleting code is hard because you must prove "nobody uses this." Fallow models the entire dependency graph, turning "is this referenced?" into a queryable fact. For any "prove non-existence" problem, ask: can we materialize the relevant structure?
Separate static candidates from runtime confirmation. Static analysis is fast but yields "may be unused"; runtime evidence is slower but yields "definitely unused." Fallow splits them into free and paid tiers, each doing what it does best. Evaluate any tooling by asking whether it delivers static candidates or runtime confirmation.
Design machine-readable interfaces first. Fallow's agent interface is a JSON contract and exit codes — not pretty terminal text. When your tool may be called by AI, stable machine output matters more than human UI.
Adopt progressively: report first, block later. Fallow defaults to blocking only new issues in changed files, isolates existing debt via baselines, and lets teams tighten gradually. This is a mature rollout pattern for any engineering gate.
Zero-config lowers the activation energy. 100+ framework plugins and auto-detected entry points mean the first run "just works." A tool's value often hinges on how easily it gets used.
If you have a TS/JS project haunted by "code nobody dares delete," run npx fallow and see. It doesn't execute your code, doesn't require Node or a TypeScript compiler — a single binary surfaces the entire codebase's health in milliseconds.
GitHub: github.com/fallow-rs/fallowSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Geek Labs
Daily shares of interesting GitHub open-source projects. AI tools, automation gems, technical tutorials, open-source inspiration.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
