Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions analysis/boundaries.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ keywords: ["architecture boundaries", "import rules", "module boundaries", "laye
icon: "layer-group"
---

Architecture boundaries catch a UI component that imports the database client, or one feature that imports another. You define <Tooltip tip="Named groups of files matched by glob patterns, for example 'ui' matches src/components/**">zones</Tooltip> and declare which zones may import from which. `fallow dead-code` then reports each import that breaks a rule.
Architecture boundaries catch a UI component that imports the database client, or one feature that imports another. You define <Tooltip tip="Named groups of files matched by glob patterns, for example 'ui' matches src/components/**">zones</Tooltip> and declare which zones may import from which. `fallow architecture` then reports each import that breaks a rule.

```bash
fallow dead-code --boundary-violations
fallow architecture --boundaries
```

<Info>
`fallow dead-code` includes boundary violations in its output by default. To show only boundary issues, pass `--boundary-violations`.
`fallow architecture` reports boundary violations together with import cycles and policy violations. To show only boundary issues, pass `--boundaries`. To see the rules for a file before you edit it, run [`fallow guard`](/cli/guard). `fallow dead-code` also reports boundary violations until the next major version. Its `--boundary-violations` flag is a deprecated alias for `fallow architecture --boundaries`.
</Info>

## Quick start with presets
Expand Down Expand Up @@ -330,16 +330,16 @@ All output formats include boundary violations:

<Tabs>
<Tab title="Human">
```bash title="$ fallow dead-code --boundary-violations"
── Structure ─────────────────────────────────────
```bash title="$ fallow architecture --boundaries"
── Architecture ─────────────────────────────────────

● Boundary violations (2)
src/components/Button.tsx:1 → src/server/db/client.ts (shared → server)
src/features/auth/login.ts:3 → src/features/billing/api.ts (features/auth → features/billing)
Imports that cross defined architecture zone boundaries
https://fallow.tools/docs/explanations/dead-code/#boundary-violations

✗ 2 violations (0.05s)
✗ 2 boundary violations (0.05s)
```
</Tab>
<Tab title="JSON">
Expand Down Expand Up @@ -377,8 +377,8 @@ All output formats include boundary violations:
## See also

<CardGroup cols={3}>
<Card title="fallow dead-code" icon="terminal" href="/cli/dead-code">
CLI reference for the dead code command and all issue type filters.
<Card title="fallow architecture" icon="terminal" href="/cli/architecture">
CLI reference for import cycles, boundaries, and policy rules.
</Card>
<Card title="Rules & Severity" icon="scale-balanced" href="/configuration/rules">
Set boundary violations to error, warn, or off.
Expand Down
4 changes: 2 additions & 2 deletions analysis/dead-code.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Fallow reports these core issue types:
| **Test-only dependencies** | Production dependencies that only test files import (move them to devDependencies) |
| **Stale suppressions** | `fallow-ignore` comments or `@expected-unused` JSDoc tags that no longer match any issue |

Fallow also has framework-specific rules, such as unused component props and route collisions, and opt-in rules, such as private type leaks. To set the severity of a rule, see [Rules & severity](/configuration/rules). To see the filter flag of each issue type, run `fallow dead-code --help`.
Fallow also has framework-specific rules, such as unused component props and route collisions, and opt-in rules, such as private type leaks. To set the severity of a rule, see [Rules & severity](/configuration/rules). To see the filter flag of each issue type, run `fallow dead-code --help`. For circular dependencies, boundary violations, and the other architecture findings, use [`fallow architecture`](/cli/architecture).

Typical output with more than one issue type:

Expand Down Expand Up @@ -598,7 +598,7 @@ The comparison finds:

## Circular dependency performance

`fallow dead-code --circular-deps` runs the full analysis (dead code, dependencies, boundaries, and cycles). All runs are cold, with fallow 2.100.0 on an Apple M5.
`fallow dead-code --circular-deps` runs the full analysis (dead code, dependencies, boundaries, and cycles). All runs are cold, with fallow 2.100.0 on an Apple M5. The flag is now a deprecated alias for `fallow architecture --cycles`, which runs the same analysis.

| Project | Files | Time | Cycles |
|:--------|------:|-----:|-------:|
Expand Down
153 changes: 153 additions & 0 deletions cli/architecture.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
title: "fallow architecture"
description: "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."
keywords: ["fallow architecture", "architecture", "circular dependencies", "import cycles", "boundaries", "boundary violations", "rule packs", "policy", "CLI"]
icon: "terminal"
---

`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

```bash
fallow architecture
fallow architecture --cycles
fallow architecture --boundaries --changed-since main
```

The command runs the same analysis as [`fallow dead-code`](/cli/dead-code) with only these issue types selected. The JSON output is the `dead-code` envelope (`kind: "dead-code"`). The arrays, the finding ids, the exit codes, and the baselines are the same as on `dead-code`.

<Info>
Run [`fallow guard`](/cli/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.
</Info>

## Options

### Selection

| Flag | Selects |
|:-----|:--------|
| `--cycles` | Circular dependencies, re-export cycles, and package cycles |
| `--boundaries` | Boundary violations, boundary coverage, and forbidden calls |
| `--policy` | Rule-pack policy violations |

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

### Scoping

| Flag | Description |
|:-----|:------------|
| `[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`](/cli/dead-code#finding-id-query). |

The [global flags](/cli/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 and give the same machine output. Only the human headings are different:

| Command | Same issues as |
|:--------|:---------------|
| `fallow architecture --cycles` | `fallow dead-code --circular-deps --re-export-cycles --package-cycles` |
| `fallow architecture --boundaries` | `fallow dead-code --boundary-violations` |
| `fallow architecture --policy` | `fallow 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

```bash title="$ fallow architecture (excerpt)"
── 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`:

```json title="$ fallow architecture --boundaries --format json (excerpt)"
{
"kind": "dead-code",
"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
}
]
}
```

## Exit codes

| Code | Meaning |
|:-----|:--------|
| `0` | No finding with error severity. |
| `1` | At least one finding has error severity. |
| `2` | Invalid 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`](/configuration/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`.

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.

## Examples

```bash
# 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](/cli/global-flags).

## See also

<CardGroup cols={2}>
<Card title="fallow guard" icon="terminal" href="/cli/guard">
See the architecture rules for a file before you edit it.
</Card>
<Card title="Architecture boundaries" icon="layer-group" href="/analysis/boundaries">
Define zones and the imports that each zone allows.
</Card>
<Card title="Issue types" icon="book" href="/explanations/dead-code#circular-dependencies">
What cycles, boundary violations, and policy violations mean, and when to act.
</Card>
<Card title="fallow dead-code" icon="terminal" href="/cli/dead-code">
The dead code command and its issue type filters.
</Card>
</CardGroup>
24 changes: 18 additions & 6 deletions cli/dead-code.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ icon: "terminal"
`fallow dead-code` finds the code that nothing uses, so you can delete it and keep the codebase smaller. Fallow starts at your entry points, traces all reachable exports, and reports each file, export, dependency, and type that is not used.

<Tip>
Bare `fallow` runs **all analyses** (dead code, duplication, and health). To run only the dead code analysis, use `fallow dead-code`. `fallow check` is still a hidden alias for `fallow dead-code`.
Bare `fallow` runs **all analyses** (dead code, architecture, duplication, and health). To run only the dead code analysis, use `fallow dead-code`. For import cycles, boundaries, and policy rules, use [`fallow architecture`](/cli/architecture). `fallow check` is still a hidden alias for `fallow dead-code`.
</Tip>

```bash
Expand Down Expand Up @@ -57,11 +57,11 @@ fallow check # Hidden alias for fallow dead-code
| `--unresolved-imports` | Report only unresolved imports |
| `--unlisted-deps` | Report only unlisted dependencies |
| `--duplicate-exports` | Report only duplicate exports |
| `--circular-deps` | Report only circular dependencies |
| `--re-export-cycles` | Report only re-export cycles (barrel files that re-export from each other in a loop, or self-loops). See [explanations/dead-code#re-export-cycles](/explanations/dead-code#re-export-cycles) |
| `--package-cycles` | Report only package cycles (workspace packages that import each other in a loop). See [explanations/dead-code#package-cycles](/explanations/dead-code#package-cycles) |
| `--boundary-violations` | Report only boundary violations |
| `--policy-violations` | Report only configured rule-pack violations, including banned usages and gdp-ts proof producers outside allowed files. See [Policy violations](/explanations/dead-code#policy-violations). |
| `--circular-deps` | Deprecated alias for [`fallow architecture --cycles`](/cli/architecture). Report only circular dependencies. |
| `--re-export-cycles` | Deprecated alias for [`fallow architecture --cycles`](/cli/architecture). Report only re-export cycles (barrel files that re-export from each other in a loop, or self-loops). See [explanations/dead-code#re-export-cycles](/explanations/dead-code#re-export-cycles) |
| `--package-cycles` | Deprecated alias for [`fallow architecture --cycles`](/cli/architecture). Report only package cycles (workspace packages that import each other in a loop). See [explanations/dead-code#package-cycles](/explanations/dead-code#package-cycles) |
| `--boundary-violations` | Deprecated alias for [`fallow architecture --boundaries`](/cli/architecture). Report only boundary violations. |
| `--policy-violations` | Deprecated alias for [`fallow architecture --policy`](/cli/architecture). Report only configured rule-pack violations, including banned usages and gdp-ts proof producers outside allowed files. See [Policy violations](/explanations/dead-code#policy-violations). |
| `--stale-suppressions` | Report only stale suppression comments and `@expected-unused` JSDoc tags |
| `--unused-catalog-entries` | Report only unused pnpm catalog entries |
| `--empty-catalog-groups` | Report only empty named pnpm catalog groups |
Expand All @@ -71,6 +71,18 @@ fallow check # Hidden alias for fallow dead-code
| `--include-dupes` | Also run duplication analysis and link its results to dead code findings |
| `--finding-id <ID>` | Report only the findings with this `finding_id`. Repeat the flag or pass a comma-separated list. The JSON output adds a `finding_id_query` answer. A malformed id exits 2. See [`finding_id_query`](#finding-id-query). |

The five deprecated aliases continue to work in version 3.

<Note>
`fallow dead-code` continues to report circular dependencies, re-export cycles, package cycles, boundary violations, and policy violations by default until the next major version. When the human output reports such a finding, fallow prints one hint on stderr:

```text
Tip: run `fallow architecture` for import cycles, boundaries and policy rules. A future major version removes them from `fallow dead-code`.
```

`--quiet` and the machine formats do not print the hint. The JSON, SARIF, CodeClimate, compact, and markdown output do not change. Use [`fallow architecture`](/cli/architecture) for these findings.
</Note>

### Scoping

| Flag | Description |
Expand Down
4 changes: 2 additions & 2 deletions cli/global-flags.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ The `--dupes-*` flags apply to combined mode. When you do not set one, fallow us
| `--report-path-prefix <PREFIX>` (alias: `--annotations-path-prefix`) | Override the repository-root offset that fallow adds in front of each path in the CI formats. An empty string disables the offset. See [Repository-root paths in CI formats](#repository-root-paths-in-ci-formats). |
| `--group-by <MODE>` | Group output by CODEOWNERS ownership (`owner`), first directory component (`directory`), workspace package (`package`), or GitLab CODEOWNERS section (`section`). `json`, `human`, `sarif` and `codeclimate` show the groups. For `dead-code`, `compact` and `markdown` also show the groups. For `health`, `markdown` and `github-summary` also show the groups. All other formats render one flat document and print a warning on stderr. See [Grouped output](#grouped-output). |
| `--summary` | In human output, show only the issue counts per category, without the individual items. JSON output does not change. |
| `--only <dead-code,dupes,health>` | Run only specific analyses when no subcommand is given. `check` is an alias for `dead-code`. |
| `--skip <dead-code,dupes,health>` | Skip specific analyses when no subcommand is given |
| `--only <dead-code,architecture,dupes,health>` | Run only specific analyses when no subcommand is given. `check` is an alias for `dead-code`. `architecture` selects the import cycles, boundary violations, and policy violations. See [`fallow architecture`](/cli/architecture). |
| `--skip <dead-code,architecture,dupes,health>` | Skip specific analyses when no subcommand is given |
| `--coverage <PATH>` | In combined mode, give Istanbul coverage data to the health analysis. Same fallback chain as [`fallow health --coverage`](/cli/health#options). |
| `--coverage-root <PATH>` | Absolute prefix to strip from Istanbul coverage paths in combined mode. See [`fallow health --coverage-root`](/cli/health#options). |
| `--dupes-baseline <PATH>` | In combined mode, hide the clone groups in a baseline that `fallow dupes --save-baseline` wrote. With a subcommand, use `fallow dupes --baseline`. |
Expand Down
13 changes: 11 additions & 2 deletions cli/guard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fallow guard src/ui/App.ts src/db/query.ts --format json
```

<Info>
`guard` shows the rules before an edit. For violations that already exist in the code, run [`fallow dead-code`](/cli/dead-code) or [`fallow audit`](/cli/audit), which report `boundary-violation` and `policy-violation` findings.
`guard` shows the rules before an edit. For violations that already exist in the code, run [`fallow architecture`](/cli/architecture) after the edit. [`fallow audit`](/cli/audit) also reports `boundary-violation` and `policy-violation` findings in the changed files.
</Info>

## Output
Expand Down Expand Up @@ -154,11 +154,20 @@ Call `guard` on the files you are about to change, while you can still choose wh
fallow guard --format json --quiet <files>
```

The `guard` MCP tool gives the same output. The [MCP integration guide](/integrations/mcp) describes it.
After the edit, run `fallow architecture` to find the violations in the code:

```bash
fallow architecture --format json --quiet
```

The `guard` MCP tool gives the same output as `fallow guard`. The [MCP integration guide](/integrations/mcp) describes it.

## See also

<CardGroup cols={2}>
<Card title="fallow architecture" icon="terminal" href="/cli/architecture">
Find import cycles, boundary violations, and policy violations after an edit.
</Card>
<Card title="Architecture boundaries" icon="layer-group" href="/analysis/boundaries">
How fallow detects imports that cross zone boundaries.
</Card>
Expand Down
Loading