AI agents now write a large share of the code in my projects. They deliver fast and well, with a constant tendency to extend what already exists rather than create a new concept. Request after request, a 20-line function grows to 100, a 100-line file grows to 500, and names only describe part of what they contain.

Fallow corrects this drift with remarkable efficiency. Before each commit, my agent runs Fallow to measure the project's functions and files. Until the verdict is green, it keeps splitting. This procedure guarantees code made of small functions, organized in single-responsibility files, whose names say exactly what they do.


Fallow in a nutshell

Fallow is an open source static analyzer for TypeScript and JavaScript, released under the MIT license as a single Rust binary. It builds a complete graph of the repository (modules, exports, dependencies, functions) and derives four families of analyses from it:

  • Complexity: Cyclomatic and cognitive complexity of every function, maintainability score of every file and a project health score out of 100.
  • Dead code: Detection of files, exports, types and dependencies that nothing uses anymore.
  • Duplication: Spotting blocks copied from one file to another, in TypeScript and JavaScript code as well as in stylesheets and UI components.
  • Architecture: Enforcement of import boundaries (UI, business logic, data) and detection of circular dependencies.

The analyzer embeds no language model: the same input always produces the same result. It runs on its own, without the TypeScript compiler or a Node.js runtime. According to the benchmarks published by the project, it can analyze a repository as large as the Next.js monorepo (20,558 files) in under 3 seconds.

This determinism makes it the right partner for an AI agent: the agent proposes, Fallow measures.

Sources: the project's BENCHMARKS.md (June 2026 measurements) and fallow.tools, accessed in October 2026.


A referee in the agent loop

At the pace agents work, I no longer review every line one by one. Asking an agent to “write simple code” does not ensure that the constraint is met.

Fallow becomes the safeguard of every commit. The diagram below shows the loop the agent follows for each task:

  1. AI agent1. DevelopmentImplementation of the request, with no particular constraint
  2. Fallow2. MeasurementFlags overly complex functions, files to split, unused exports and duplicated blocks
  3. AI agent3. SplittingExtraction of steps into named functions and of responsibilities into dedicated files
  4. Git4. CommitAccepted only on a “pass” verdict
The lock blocks the commit as long as Fallow returns a “fail” verdict.

Splitting happens at two scales:

  • Function: Default thresholds of 20 for cyclomatic complexity, 15 for cognitive complexity and 60 lines per function, which I keep as they are.
  • File: Maintainability score computed from size, complexity density, dead code and dependencies, along with prioritized recommendations such as “split a file that too many others depend on” or “extract the parseRow function from a 520-line file”.

Fallow does not say how to fix things: it points out what is too long, too nested, too central or repeated, and leaves it to the agent to split and organize.

Source: Health explained, Fallow documentation accessed in October 2026.


Hands-on feedback

I coded a small TypeScript bot that automatically books my fitness classes, whose spots fill up within minutes. Once it was stable, I handed the project to an AI agent to integrate it into Home Assistant, with a graphical interface, controllable bookings and phone notifications.

Fitness class booking bot interface in Home Assistant

The agent quickly delivered a working project, but every change had been grafted onto the existing code. A single function handled the API login, fetching the schedule, picking the time slot and then booking, and the whole interface lived in a single file.

Once Fallow was plugged in, the agent isolated each business step in a dedicated function, with a name that says what it does. It then applied the same responsibility-based split at the file level.

The result shows across three parts of the project:

  • Booking: The main function goes from 88 to 28 lines and delegates login, schedule, slot selection and booking to 4 functions named after their step.
  • Interface: The App.tsx file goes from 501 to 116 lines, spread across 7 reusable components, a shared types file and a dedicated hook.
  • Notifications: Notification sending, written 3 times, now lives in a single place under the name notifyBookingSuccess.

A source of truth to keep the agent on track

An AI agent works on a project the way a developer would. It looks for the right file, reads what surrounds it and changes what it understands. A project generated prompt after prompt, never refactored, picks up the traits of spaghetti code from the very first requests: files with mixed responsibilities, approximate names, duplicated logic. In that context, finding the right file forces the agent to read more, and changing what it understands is no longer enough, because side effects multiply.

Fallow reverses this slope without requiring software architecture expertise. Splitting, naming and organizing rules are measured and the verdict is binding on the agent, without having to spell them out in every prompt or check them during review. The benefit shows on three levels:

  • Fewer regressionsShort functions and single-responsibility files, where every change stays confined to the part concerned.
  • Fewer tokensNavigation guided by explicit names, without rereading entire files to find the right line.
  • More controlAn objective, reproducible criterion to validate the agent's work, where a natural-language instruction remains unverifiable.

Hand Fallow to your agent. On every commit, it splits, names and organizes the code without you having to dictate each rule. You keep a readable project that costs less to evolve, and every new request starts from a healthy base. Quality is no longer decreed, it is verified.

Comparing Multiple Fields with Angular

How to validate two form fields by comparing them? Let's verify multiple fields with a...