Skip to content
Back to archipelago.banuacoder.com

Monorepo Toolkit

Dependency Graph Enforcement ​

What you'll learn ​

  • Visualizing package dependencies across your monorepo
  • Defining and enforcing layered dependency rules
  • Detecting circular dependencies before they cause build issues
  • Integrating graph checks into CI as a quality gate

Prerequisites ​

  • An existing Archipelago monorepo (see Monorepo Scaffolding)
  • Graphviz installed if you want to render DOT output to an image (brew install graphviz on macOS)

The graph command is part of the free monorepo_toolkit, so every generated project already has it. There is nothing to generate separately.

Step 1: Visualize Your Dependencies ​

Generate a visual graph of all package relationships:

bash
# Text overview to the terminal (default)
dart run monorepo_toolkit graph visualize

# DOT format, then render to PNG
dart run monorepo_toolkit graph visualize --format dot --output deps.dot
dot -Tpng deps.dot -o deps.png

# Mermaid for Markdown, or JSON for tooling
dart run monorepo_toolkit graph visualize --format mermaid --output deps.md
dart run monorepo_toolkit graph visualize --format json --output deps.json

Get headline numbers (package count, edges, most depended-on packages) with:

bash
dart run monorepo_toolkit graph stats

Step 2: Understand the Layer Rules ​

graph validate enforces the architecture rules. They are built into the toolkit, not read from a config file. Dependencies must flow downward:

apps/ -> features/ -> infrastructure/ -> packages/ -> shared/ -> utilities/
RuleDescription
api-restricted-deps*_api packages depend only on shared/, utilities/ and other *_api packages
no-impl-cross-dep*_impl packages cannot depend on *_impl packages of other features
shared-no-upward-depshared/ cannot depend on features/, infrastructure/, packages/ or apps/
utility-no-upward-deputilities/ cannot depend on features/, infrastructure/, packages/ or apps/
no-upward-deppackages/ cannot depend on feature impl or app packages
no-devtools-depApp packages cannot depend on devtools packages

Packages are categorized by their directory (apps/, features/, infrastructure/, shared/, ...) and _api/_impl suffix. See Dependency Graph for the full table.

Step 3: Enforce Rules Locally ​

bash
dart run monorepo_toolkit graph validate

# Include the package categories and passing checks
dart run monorepo_toolkit graph validate --verbose

When a rule is broken, the command lists each violation and exits with code 1. Fix it by moving the shared type down into a package the offender is allowed to depend on (usually an _api package or shared/).

Step 4: Detect Circular Dependencies ​

Circular dependencies can cause build failures and indicate architectural issues:

bash
dart run monorepo_toolkit graph cycles

It prints each detected cycle and exits with code 1. Pass --no-fail to report cycles without failing the command.

Step 5: Integrate with CI ​

Add graph enforcement to your PR validation to prevent architectural drift:

yaml
- name: Validate dependency rules
  run: dart run monorepo_toolkit graph validate

- name: Check for circular dependencies
  run: dart run monorepo_toolkit graph cycles

- name: Generate dependency graph artifact
  if: always()
  run: |
    dart run monorepo_toolkit graph visualize --format dot --output deps.dot
    dot -Tpng deps.dot -o deps.png

- name: Upload graph
  if: always()
  uses: actions/upload-artifact@v4
  with:
    name: dependency-graph
    path: deps.png

Key Customization Points ​

CustomizationWhere to Change
Output formatgraph visualize --format (text, dot, mermaid, json)
Write to a filegraph visualize --output
Detailed validation outputgraph validate --verbose
Cycles as warning onlygraph cycles --no-fail
The rules themselvesdevtools/scripts/dependency_graph/lib/src/commands/validate_command.dart (generated into your project, so you own it)

Next Steps ​