Codebase intelligence for TypeScript and JavaScript.
Free static analysis of code and styles, optional paid runtime intelligence (Fallow Runtime).
Quality, risk, architecture, dependencies, duplication, and design-system drift, for humans, CI, and the agents writing your code. Rust-native · zero-config · sub-second · no AI inside the analyzer
---
Fallow turns a frontend repository into a trusted quality report: health score, changed-code risk, hotspots, duplication, architecture issues, dependency hygiene, styling consistency, and cleanup opportunities. It helps you answer:
- What changed?
- What got riskier?
- What should I review?
- What should I refactor?
- What can be safely removed?
Fallow is built for maintainers, CI pipelines, editors, and AI agents that need structured evidence instead of guesses. No AI inside the analyzer. Fallow produces deterministic findings, typed output contracts, and traceable explanations that downstream tools can trust.
Fallow dogfoods its shipped code and styling surfaces in CI: the VS Code extension, npm wrapper package, and authored CSS-facing fixtures are analyzed with fallow on every relevant change.
## Quick start
Run a changed-code audit:
```bash
npx fallow audit
```
Example output:
```
Audit scope: 7 changed files vs main
-- Dead Code ---------------------------------------
x 7 unused dependencies · 14 dev/optional dependencies
21 issues · 1 suppressed · 0 stale suppressions
-- Duplication -------------------------------------
x 3 clone families touching changed files
-- Complexity --------------------------------------
! 2 changed functions above threshold
```
Cleanup opportunities include unused files, unused exports, unused dependencies, stale suppressions, and other code that no longer appears to carry product value.
For machine-readable output:
```bash
npx fallow audit --format json
```
For quality scoring and refactor targets:
```bash
npx fallow health --score --hotspots --targets
```
For cleanup-specific findings:
```bash
npx fallow dead-code
```
123 framework plugins. No Node.js runtime required for static analysis. No config needed for the first run.
## What is Fallow?
Fallow is a codebase intelligence engine for TypeScript and JavaScript projects, code and the styles they ship.
It analyzes your repository as a system, not just as a list of files. It connects static structure, dependency relationships, duplication, complexity, architecture boundaries, styling consistency, package hygiene, and optional runtime evidence into one quality report.
Fallow helps teams:
- review risky pull requests before they merge
- track quality trends over time
- find architectural hotspots
- understand dependency hygiene
- detect duplicated logic
- explain why code is used, unused, risky, or safe to remove
- provide structured repo context to AI agents and editor tools
Linters check files. TypeScript checks types. Fallow checks the codebase. Fallow does not use AI to invent findings. It produces deterministic evidence that humans and agents can inspect.
## Install
```bash
npm install --save-dev fallow # or: pnpm add -D fallow / yarn add -D fallow / bun add -d fallow
```
Installs the CLI, LSP server, MCP server, and version-matched Agent Skill into `node_modules`. For one-off CLI use, run `npx fallow`; Rust users can also run `cargo install fallow-cli`.
Interactive human runs can show a one-line upgrade hint when a cached latest-version check says the local fallow is stale. Machine formats, CI, quiet runs, and non-TTY agent paths never show the hint; set `FALLOW_UPDATE_CHECK=off` to disable the hint and background check.
Parsing `fallow --format json` in TypeScript? `import type { CheckOutput } from "fallow/types"` gives you the full output contract, version-pinned to your installed CLI.
### Docker
Build the local CLI image from this repository:
```bash
docker build -t fallow:local .
```
Run fallow against a project by mounting it at `/workspace`:
```bash
cd /path/to/project
docker run --rm -v "$PWD:/workspace" --user "$(id -u):$(id -g)" fallow:local audit --format json --quiet
```
The `--user` mapping keeps `.fallow/` caches and generated reports owned by your host user. It also lets `fallow audit` use git base detection without Git's dubious-ownership guard blocking the mounted repository. The image includes git, Node.js, npm, and Corepack; fallow does not install your project dependencies automatically.
For Compose, copy `examples/docker/compose.yaml` into the target project after building the image, then run:
```bash
docker compose run --rm fallow audit --format json --quiet
```
Fallow is a one-shot CLI, not a long-running service. In Portainer or other stack tools, use a one-shot run command instead of deploying it as an always-on service, or override the command for an interactive shell. Container exit codes are the fallow process exit codes, so CI can gate on the `docker run` or `docker compose run` result directly.
On Linux and WSL, the commands above work as written. On Windows outside WSL, pass an absolute project path accepted by Docker Desktop and keep the mounted working directory at `/workspace`. For containerized runtime coverage inventory, use the container path prefix:
```bash
docker run --rm -v "$PWD:/workspace" --user "$(id -u):$(id -g)" fallow:local coverage upload-inventory --path-prefix /workspace --format json --quiet
```
Programmatic Node API:
```bash
npm install @fallow-cli/fallow-node # or: pnpm/yarn/bun add @fallow-cli/fallow-node
```
```ts
import { detectDeadCode, detectDuplication, computeHealth } from '@fallow-cli/fallow-node';
const findings = await detectDeadCode({ root: process.cwd() });
const dupes = await detectDuplication({ root: process.cwd(), mode: 'mild', minTokens: 30 });
const health = await computeHealth({ root: process.cwd(), score: true, ownershipEmails: 'handle' });
```
## What Fallow reports
### Quality score
A compact health score for the current state of the repository, with targets for maintainability, complexity, duplication, dependency hygiene, and architecture.
### PR risk
Changed-code analysis (`fallow audit`) that highlights files and symbols most likely to need review before merge, including styling drift in CSS and CSS-in-JS. Returns a verdict (pass / warn / fail) and an attribution split between findings the PR introduced and pre-existing ones.
### Hotspots
Functions, files, and packages that combine complexity, churn, size, coupling, and (with the runtime layer) runtime importance.
### Duplication
Clone families and duplicated implementation patterns that increase maintenance cost. Four detection modes from exact token match to semantic clones with renamed variables. Covers JS, TS, CSS-family stylesheets, Vue and Svelte template and style regions, and Astro template and style regions.
### Design-system styling
Styling analytics for CSS, parser-level Sass/Less, CSS Modules, Tailwind/shadcn/CVA, StyleX/PandaCSS, vanilla-extract, styled-components, and Emotion. `fallow audit` surfaces token drift, raw one-off style values, near-duplicate tokens, dead styling surface, broken references, duplicate declaration blocks, and selector complexity in the same JSON stream as JS/TS findings. Fallow does not replace stylelint, a Sass/Less compiler, or a formatter: it leaves property syntax, value syntax, vendor prefixes, quotes, whitespace, declaration ordering, and preprocessor expansion to dedicated CSS tooling.
### Architecture
Circular dependencies, boundary violations across layers and modules, re-export chains, and other dependency-graph issues. Zero-config presets for bulletproof, layered, hexagonal, and feature-sliced architectures. Framework correctness checks catch Next.js `"use client"` files that export a server-only or route-segment config name (such as `metadata`, `revalidate`, or a route HTTP method) before the build does. They also flag barrels that re-export both client and server-only modules, and `"use client"` / `"use server"` directives placed below an import where the bundler silently ignores them. Whole-project App Router checks catch route collisions (two files resolving to the same URL across route groups, a `next build` failure) and dynamic-segment name conflicts (`[id]` vs `[slug]` at the same position), scoped per app-root so monorepos with multiple Next apps are not false-flagged. They also flag Server Actions exported from a `"use server"` file that no code in the project calls (no import-and-call, no `action={fn}` binding, no `