Skip to content

lindseystead/ArchGuard

Repository files navigation

ArchGuard

Architecture enforcement for React and TypeScript projects.

ArchGuard is a local-first CLI that checks layer boundaries, flags a small set of structural UI violations, and fails fast in local development or CI when code breaks the configured architecture.

Overview

ArchGuard is intended for teams that:

  • use React and TypeScript
  • organize code into explicit layers such as domain, features, and ui
  • want deterministic architectural checks instead of review-only enforcement

This is not a general-purpose static analysis framework. The current implementation is deliberately narrow and opinionated.

Why Use ArchGuard

ArchGuard is aimed at teams that want architecture enforcement without introducing a test DSL or a large analysis framework.

  • CLI-first: it runs as a direct command in local development, pre-commit hooks, and CI.
  • Deterministic: it uses explicit layer rules from architecture.yaml instead of inference-heavy heuristics for boundaries.
  • Incremental rollout: baseline mode lets teams adopt the tool without stopping work to clean all historical violations first.
  • Contributor guidance included: init generates AGENTS.md and .archguard/ARCHITECTURE_RULES.md from the same source of truth.

The tradeoff is deliberate: smaller surface area, faster setup, and less configurability than broad architecture-testing libraries.

Features

  • Layer Boundary Enforcement: Blocks imports that violate configured layer rules.
  • Component Logic Checks: Flags loops and similar logic patterns inside React components.
  • UI Data Access Checks: Flags direct data fetching inside UI components.
  • Cycle Detection: Detects circular dependencies across local imports the resolver can map.
  • Baseline Mode: Supports incremental rollout by suppressing already-known violations.
  • Structured Output: Emits json and sarif for CI wrappers and code-scanning workflows.
  • Path Alias Resolution: Resolves relative imports and common tsconfig.json aliases before rule evaluation.

Quick Start

Installation

The repository root remains private because it also hosts the GitHub Action and the monorepo workspace setup. The publishable CLI is the @archguard/cli workspace package.

Install from npm

Use the npm install path only after you have verified that the published package name and scope point to this repository's release.

npm install --save-dev @archguard/cli
npx archguard init

If npx archguard does not resolve after installation, the installed registry package is not exposing the expected archguard binary. In that case, verify the published package metadata before using the npm path.

Publishing these packages under their current names requires control of the @archguard npm scope.

Install from this repository

If you are evaluating the project from source before installing from npm, use the local link workflow:

npm install
npm run build
npm link

After linking, the archguard command is available in other local projects on the same machine.

For release validation before publishing the workspace packages:

npm run release:check

To publish the workspace packages in dependency order after authenticating with npm:

npm run release:publish

A step-by-step release checklist is included in PUBLISHING.md.

Initialize a Project

archguard init

This command:

  • verifies that the target project looks like a React + TypeScript repository
  • writes architecture.yaml
  • writes AGENTS.md if the file does not already exist
  • writes .archguard/ARCHITECTURE_RULES.md
  • installs a pre-commit hook only if no existing hook is present

Run Checks

archguard check

Adopt Incrementally

archguard check --update-baseline
archguard check --baseline

--update-baseline writes .archguard-baseline.json. Later runs with --baseline suppress matching historical violations and fail only on new ones.

Configuration

ArchGuard reads architecture.yaml from the current working directory or the nearest parent directory.

layers:
  domain:
    allowedImports: []
  features:
    allowedImports: [domain, shared]
  ui:
    allowedImports: [features, shared]

rules:
  noBusinessLogicInComponents: true
  noDataFetchingInUI: true
  enforceFeatureBoundaries: true
  noCircularLayerDeps: true

Available preset:

  • feature-sliced-react

Command Reference

Initialize with Default Rules

archguard init

Initialize with the Feature-Sliced Preset

archguard init --preset feature-sliced-react

Standard Check

archguard check

Structured Output

archguard check --format json
archguard check --format sarif

Baseline Workflow

archguard check --baseline
archguard check --update-baseline

GitHub Actions

This repository includes a composite GitHub Action that installs and runs ArchGuard in the checked-out repository.

Basic Usage

- uses: actions/checkout@v4
- uses: lindseystead/ArchGuard@v1
  with:
    format: json

Run from a Subdirectory

- uses: actions/checkout@v4
- uses: lindseystead/ArchGuard@v1
  with:
    format: json
    working-directory: apps/web

Upload SARIF to Code Scanning

- uses: actions/checkout@v4
- id: archguard
  continue-on-error: true
  uses: lindseystead/ArchGuard@v1
  with:
    format: sarif
    output-file: reports/archguard.sarif
- if: ${{ always() }}
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: reports/archguard.sarif
- if: ${{ steps.archguard.outcome == 'failure' }}
  run: exit 1

Project Structure

archguard/
├── packages/
│   ├── core/         # Shared types, config loading, parsing, and resolution helpers
│   ├── cli/          # Command-line entry point and reporting
│   ├── rules-react/  # React-specific rule implementations
│   └── guidance/     # Project guidance document generator
└── architecture.schema.ts

Example Project

A passing example project is included in examples/react-layered-app. It shows the intended folder layout and a minimal code path that satisfies the default layered rules.

Technical Notes

ArchGuard uses the TypeScript compiler API to parse .ts and .tsx files.

At a high level:

  • import declarations are extracted from the AST
  • file paths are mapped to layers by matching configured folder names
  • relative imports and common tsconfig.json path aliases are resolved to build an import graph
  • React component checks inspect component AST nodes for loops, complex conditionals, and known fetch calls

The AGENTS.md and .archguard/ARCHITECTURE_RULES.md files are generated reference documents for contributors and supporting tooling. They are not the source of truth and they are not the enforcement mechanism. Enforcement happens in the CLI through architecture.yaml.

Known Limitations

  • component behavior checks are heuristic-based rather than semantically complete
  • layer detection depends on directory names matching configured layer names
  • advanced TypeScript project references and non-standard workspace resolution are not fully supported yet
  • circular dependency detection is limited to imports the CLI can resolve to local files
  • the default pre-commit integration installs only when no hook already exists

These are explicit product constraints, not hidden behavior.

Testing

Run the full suite from the repository root:

npm test

All workspace packages now run real tests as part of the root suite. The root test command is the expected verification step before pushing changes.

License

MIT. See LICENSE.

About

ArchGuard is a local, deterministic architecture enforcement tool for React + TypeScript projects that prevents AI-assisted code from violating structural boundaries by enforcing layered dependencies, separation of concerns, and hard commit-time gates.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors