Skip to content
Fallow home
All docs pages

fallow architecture

Check the structure of your code after an edit. Fallow architecture reports circular dependencies, re-export cycles, package cycles, boundary violations, and rule-pack policy violations.

fallow architecture reports the findings that break the structure of your code:

  • circular dependencies
  • re-export cycles
  • package cycles (workspace packages that import each other in a loop)
  • boundary violations, which include boundary coverage and forbidden calls
  • rule-pack policy violations
fallow architecture
fallow architecture --cycles
fallow architecture --boundaries --changed-since main

The command runs the same analysis as fallow dead-code with only these issue types selected. The JSON output has kind: "architecture" and its own schema_version (1). With --group-by, the kind is architecture-grouped. The arrays, the finding ids, the actions, the exit codes, the gate outcomes, and the baselines are the same as on dead-code.

Run fallow guard before an edit to see the rules that apply to a file. Run fallow architecture after the edit to find the violations in the code.

Options

Selection

FlagSelects
--cyclesCircular dependencies, re-export cycles, and package cycles
--boundariesBoundary violations, boundary coverage, and forbidden calls
--policyRule-pack policy violations

Without a selection flag, the command reports all architecture issue types. You can combine the flags, for example --cycles --policy.

Scoping

FlagDescription
[PATH]Report only the findings in this file or directory. The default is the whole project. Fallow still builds the full project graph.
--file <PATH>Report only the findings in these files. Repeat the flag for more files. Fallow still builds the full project graph.
--finding-id <ID>Report only the findings with this finding_id. Repeat the flag or pass a comma-separated list. See finding_id_query.

The global flags work as on dead-code. These include --format, --quiet, --changed-since, --workspace, --baseline, and --save-baseline.

Relation to fallow dead-code

fallow architecture and dead-code with the matching filter flags find the same issues, with the same finding ids and exit codes. The JSON root kind, the schema_version, and the human headings are different:

CommandSame issues as
fallow architecture --cyclesfallow dead-code --circular-deps --re-export-cycles --package-cycles
fallow architecture --boundariesfallow dead-code --boundary-violations
fallow architecture --policyfallow dead-code --policy-violations

These five dead-code flags are deprecated aliases. They continue to work in version 3. fallow dead-code also continues to report the architecture findings by default until the next major version. In human output, dead-code prints a hint on stderr that points to fallow architecture when it reports such a finding.

Example output

── Architecture ─────────────────────────────────────

● Circular dependencies (1)
  src/static/a.ts
    → b.ts → a.ts

● Boundary violations (1)
  src/ui/App.ts:5 → src/db/query.ts (ui → db)

The output has one "Architecture" category. The sections in it are the same as in dead-code output. With --group-by, each group has its own "Architecture" heading.

In --format json, the findings are in the same arrays as in dead-code output, for example circular_dependencies, re_export_cycles, boundary_violations, and policy_violations:

{
  "kind": "architecture",
  "schema_version": 1,
  "boundary_violations": [
    {
      "from_path": "src/ui/App.ts",
      "to_path": "src/db/query.ts",
      "from_zone": "ui",
      "to_zone": "db",
      "import_specifier": "src/db/query.ts",
      "line": 5,
      "col": 9,
      "finding_id": "dc1:boundary-violation:fc28781770aac946"
    }
  ]
}

Exit codes

CodeMeaning
0No finding with error severity.
1At least one finding has error severity.
2Invalid input or configuration.

The exit codes are the same as on dead-code. A circular dependency and a boundary violation have error severity by default. A re-export cycle, a package cycle and a policy violation have warn severity by default. A rule in a rule pack can set its own severity. Change the severity in rules.

Baselines

fallow architecture reads and writes the same baseline format as dead-code. You can use a baseline from fallow dead-code --save-baseline with fallow architecture --baseline. The baseline file keeps kind: "dead-code", because it is a dead-code baseline.

A fallow architecture run reports only part of the issue types. For this reason, --fail-on-stale-baseline does not gate on fallow architecture, with any baseline. A baseline that fallow architecture --save-baseline writes lists only the architecture findings. When fallow dead-code reads such a baseline, fallow shows a warning.

Render a saved result

Save the JSON output of a run to a file. Then render the file in another format with fallow report, without a new analysis:

fallow architecture --format json -o results.json
fallow report --from results.json --format github-summary

fallow report reads the architecture and architecture-grouped kinds and renders them in every report format, the same as a direct run.

Examples

# Before an edit: the rules that apply to the file
fallow guard src/ui/App.ts --format json --quiet

# After an edit: cycles, boundaries, and policy rules
fallow architecture --format json --quiet

# Only import cycles in the files that changed since main
fallow architecture --cycles --changed-since main --format json --quiet

# Only boundary findings in one workspace
fallow architecture --boundaries --workspace web

# Adopt the check on an existing codebase
fallow architecture --save-baseline fallow-architecture-baseline.json
fallow architecture --baseline fallow-architecture-baseline.json

Bare fallow

Bare fallow also reports these findings. In human output, they show in an "Architecture" category inside the Dead Code section, after the other dead code categories. This is the same with --quiet. The JSON and the other machine formats do not change: the findings stay in the dead code part of the output.

To run only this section, pass --only architecture. To leave it out, pass --skip architecture. See global flags.

See also