npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dsyves/archguard-cli

v0.1.1

Published

Contract & Architecture Evolution Manager for NestJS — automated API diff and documentation.

Readme

🛡 ArchGuard

Contract & Architecture Evolution Manager for NestJS

Automated API diffing, breaking-change detection, and living documentation —
built for teams that move fast without breaking things.

npm version npm downloads license node TypeScript tests


📚 Table of Contents

  1. Why ArchGuard?
  2. Features
  3. Installation
  4. NestJS Setup
  5. Quick Start
  6. Configuration
  7. CLI Commands
  8. Diff Report Example
  9. CI/CD Integration
  10. Programmatic Usage
  11. Roadmap
  12. Contributing
  13. License

💡 Why ArchGuard?

| Problem | Without ArchGuard | With ArchGuard | |---------|-------------------|----------------| | API contract changes | Discovered by broken Frontend | Caught instantly, before merge | | Documentation drift | Swagger is always outdated | Auto-generated from live spec | | Change history | "Who changed this route?" 🤷 | Git-tracked diff reports forever | | Breaking changes in PR | Found in code review (maybe) | Blocked at CI, flagged automatically |


✨ Features

  • 🔍 Automatic API Snapshotting — Captures your OpenAPI/Swagger spec at any point in time
  • 🔴 Breaking-Change Detection — Flags removed endpoints, deleted required fields, changed parameter types
  • 🟡 Non-Breaking Change Tracking — Tracks added endpoints, optional parameters, response expansions
  • 📄 Markdown Diff Reports — Beautiful, readable reports committed directly into your git history
  • 📚 Living Architecture Index — Auto-maintained INDEX.md with every diff ever generated
  • 🤝 NestJS-First — Designed for the NestJS + @nestjs/swagger ecosystem; works with any OpenAPI 3.x spec
  • 🤖 GitHub Actions Integration — Posts diff reports as PR comments, blocks merges on breaking changes
  • 🔗 Git Auto-Commit — Optionally auto-commits snapshots and reports so your architecture history is always versioned
  • 📦 Library Mode — Use ArchGuard programmatically in your own scripts or tooling

📦 Installation

As a dev dependency in your NestJS project (recommended)

npm install --save-dev archguard-cli

Then add scripts to your package.json:

{
  "scripts": {
    "arch:init":     "archguard init",
    "arch:snapshot": "archguard snapshot",
    "arch:diff":     "archguard diff",
    "arch:history":  "archguard history"
  }
}

Global install (use anywhere)

npm install -g archguard-cli

Without installing (npx)

npx archguard-cli init
npx archguard-cli snapshot
npx archguard-cli diff

🏗 NestJS Setup

ArchGuard reads your live OpenAPI spec. Make sure Swagger is enabled in your NestJS app:

// src/main.ts
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('My API')
    .setVersion('1.0')
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);
  // ↑ This exposes the JSON spec at: http://localhost:3000/api-json

  await app.listen(3000);
}
bootstrap();

ArchGuard fetches http://localhost:3000/api-json by default.
You can override this in archguard.config.json or via --url.


🚀 Quick Start

# 1. Initialize ArchGuard in your NestJS project
npx archguard-cli init

# 2. Start your NestJS app
npm run start:dev

# 3. Capture the current API as a baseline snapshot
npx archguard-cli snapshot

# 4. Make changes to your API (add a route, change a DTO, remove a param...)

# 5. Generate a diff report
npx archguard-cli diff

Expected output for archguard diff:

🛡  ArchGuard Diff

✔ Current snapshot captured
✔ Analysis complete — 3 change(s) detected

────────────────────────────────────────────────────────────
  📊 Changes: 3 | 🔴 Breaking: 1
  ➕ Added: 1 endpoints | ➖ Removed: 1 | 🔄 Modified: 1
  📐 Schemas: +0 ~1 -0
────────────────────────────────────────────────────────────

✔ Report saved: ./docs/architecture/history/diff-2024-01-15T10-30-00-to-2024-01-15T14-45-00.md
✔ Diff completed! Check the report for details.

The generated report appears at ./docs/architecture/history/diff-latest.md — ready to commit and share with your Frontend team.


⚙️ Configuration

ArchGuard is configured via archguard.config.json in your project root (created automatically by archguard init).

{
  "projectName": "payments-api",
  "historyPath": "./docs/architecture/history",
  "snapshotPath": "./.archguard",
  "swaggerUrl": "http://localhost:3000/api-json",
  "notify": {
    "breakingChangesOnly": false
  },
  "git": {
    "autoCommit": true,
    "commitMessage": "chore(docs): update architecture history [skip ci]"
  }
}

| Option | Type | Default | Description | |--------|------|---------|-------------| | projectName | string | folder name | Display name for your project | | historyPath | string | "./docs/architecture/history" | Where diff reports are stored | | snapshotPath | string | "./.archguard" | Where snapshots are stored | | swaggerUrl | string | "http://localhost:3000/api-json" | URL to fetch the OpenAPI JSON spec | | notify.breakingChangesOnly | boolean | false | Only flag breaking changes | | git.autoCommit | boolean | false | Auto-commit snapshots and reports | | git.commitMessage | string | "chore(docs): ..." | Commit message template |


💻 CLI Commands

| Command | Description | Options | |---------|-------------|---------| | archguard init | Initialize ArchGuard in the current directory | --force overwrite existing config | | archguard snapshot | Capture the current OpenAPI spec | --url <url> override Swagger URL | | archguard diff | Compare latest snapshot with current spec | --url <url>, --no-commit | | archguard history | List stored snapshots and diff reports | --snapshots, --reports |

archguard init

Creates:

  • archguard.config.json — project configuration
  • .archguard/ — snapshot storage (add to .gitignore if desired)
  • docs/architecture/history/ — diff report history (commit this!)
  • Appends ArchGuard entries to .gitignore

archguard snapshot

archguard snapshot [--url http://localhost:3000/api-json]

Fetches your OpenAPI spec and saves a timestamped JSON snapshot. Always writes snapshot-latest.json as the baseline for the next diff.

archguard diff

archguard diff [--url <url>] [--no-commit]
  1. Loads snapshot-latest.json as baseline
  2. Fetches the current spec from your running app
  3. Runs the diff engine (endpoints + schemas + parameters + responses)
  4. Classifies each change as breaking, non-breaking, or informational
  5. Generates a Markdown report with Before/After details
  6. Updates INDEX.md and optionally auto-commits to git

archguard history

archguard history [--snapshots] [--reports]

Lists all snapshots and diff reports with timestamps.


📋 Diff Report Example

Generated reports look like this:

# 🛡 ArchGuard Diff Report

**Project:** payments-api  
**From:** `snapshot-2024-01-14T10-00-00.json`  
**To:** `snapshot-2024-01-15T14-30-00.json`

## 📊 Summary

| Metric | Count |
|--------|-------|
| 🔴 Breaking Changes | **2** |
| Total Changes | 5 |
| ➕ Added Endpoints | 1 |
| ➖ Removed Endpoints | 1 |
| 🔄 Modified Endpoints | 0 |
| Modified Schemas | 2 |

> ⚠️ **WARNING:** 2 breaking change(s) require immediate Frontend attention.

## 🔌 Endpoint Changes

### ➖ 🔴 `DELETE /v1/users/{id}`

**Severity:** BREAKING  
**Change:** [Users] Endpoint removed: Delete user  
**Frontend Impact:** ⚠️ Remove all calls to this endpoint from your codebase.

---

### ➕ 🟢 `POST /v2/users/{id}/deactivate`

**Severity:** NON-BREAKING  
**Change:** [Users] Endpoint added: Deactivate user  
**Frontend Impact:** New endpoint available — implement integration if needed.

🤖 CI/CD Integration

GitHub Actions

Copy .github/workflows/archguard.yml to your NestJS repository:

name: 🛡 ArchGuard API Contract Check

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  api-contract-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Start NestJS app
        run: |
          npm run start:prod &
          timeout 60 bash -c 'until curl -sf http://localhost:3000/api-json; do sleep 2; done'

      - name: Restore snapshot cache
        uses: actions/cache@v4
        with:
          path: .archguard/
          key: archguard-snapshot-${{ github.base_ref || github.ref_name }}

      - name: Run ArchGuard diff
        if: github.event_name == 'pull_request'
        run: npx archguard-cli diff --no-commit

      - name: Comment PR with diff
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const file = 'docs/architecture/history/diff-latest.md';
            if (!fs.existsSync(file)) return;
            const body = fs.readFileSync(file, 'utf-8').slice(0, 65000);
            await github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## 🛡 ArchGuard API Diff\n\n${body}`
            });

      - name: Block merge on breaking changes
        if: github.event_name == 'pull_request'
        run: |
          if grep -q "Breaking Changes | \*\*[1-9]" docs/architecture/history/diff-latest.md 2>/dev/null; then
            echo "🔴 Breaking API changes detected! Fix before merging."
            exit 1
          fi

      - name: Save snapshot on main push
        if: github.ref == 'refs/heads/main' && github.event_name == 'push'
        run: npx archguard-cli snapshot

🔧 Programmatic Usage

Use ArchGuard as a library in your own scripts:

import {
  captureSnapshot,
  loadLatestSnapshot,
  saveSnapshot,
  generateDiff,
  generateMarkdownReport,
  saveReport,
  loadConfig,
} from 'archguard-cli';

const config = loadConfig(); // reads archguard.config.json

// Capture current state
const current = await captureSnapshot(config);

// Load previous state
const previous = loadLatestSnapshot(config);

if (previous) {
  // Generate diff
  const report = generateDiff(previous, current);

  console.log(`Breaking changes: ${report.summary.breakingChanges}`);

  // Generate and save Markdown report
  const markdown = generateMarkdownReport(report, config);
  saveReport(markdown, report, config);
}

// Save current as new baseline
saveSnapshot(current, config);

🗺 Roadmap

| Phase | Feature | Status | |-------|---------|--------| | Phase 1 | Core CLI — init, snapshot, diff, history | ✅ Done | | Phase 2 | GitHub Actions CI/CD + PR comments | ✅ Done | | Phase 3 | 47 unit tests + Jest coverage | ✅ Done | | Phase 4 | Static extraction from NestJS decorators (no running server) | 🔨 In Progress | | Phase 5 | Frontend SDK type generation from diff | 📋 Planned | | Phase 6 | Web dashboard — visual architecture timeline | 📋 Planned |


🤝 Contributing

Contributions are welcome!

# 1. Fork and clone
git clone https://github.com/YvesDeSa/ArchGuard.git
cd ArchGuard

# 2. Install dependencies
npm install

# 3. Run tests
npm test

# 4. Develop with live TypeScript (no build step)
npm run dev -- snapshot --url http://localhost:3000/api-json

# 5. Build
npm run build

Project Structure

src/
├── bin/
│   └── archguard.ts       # CLI entry point (Commander.js)
├── commands/
│   ├── init.ts            # archguard init
│   ├── snapshot.ts        # archguard snapshot
│   ├── diff.ts            # archguard diff
│   └── history.ts         # archguard history
├── core/
│   ├── snapshot.ts        # Snapshot capture & persistence
│   ├── differ.ts          # OpenAPI diff engine (breaking change detection)
│   ├── reporter.ts        # Markdown report generator
│   └── git-integration.ts # simple-git auto-commit
├── utils/
│   ├── config.ts          # Config loader & path resolution
│   └── logger.ts          # Chalk-powered logger
├── types/
│   └── index.ts           # All TypeScript interfaces
├── __tests__/
│   ├── differ.test.ts     # 35 diff engine tests
│   ├── snapshot.test.ts   # Snapshot I/O tests
│   └── reporter.test.ts   # Report generation tests
└── index.ts               # Public library API

📄 License

MIT © Yves De Sá


Made with ❤️ for the NestJS community

NPM · Issues · Changelog

If ArchGuard saved you from a breaking change, give it a ⭐