How to Compare Two Architecture Snapshots Using the Archify CLI
Use the compare command in archify/bin/archify.mjs to compute a deterministic delta between two JSON-IR snapshots, producing an interactive HTML report and optional machine-readable JSON receipt.
The Archify CLI provides a purpose-built workflow for tracking architectural evolution. By comparing validated snapshots, you can visualize exactly what was added, removed, changed, moved, or rerouted between any two points in your project's history. This article walks through the complete process using the exact implementation in tt-a1i/archify.
Prerequisites: Generate Validated Snapshots
Before running a comparison, you need two validated architecture snapshots in JSON-IR format. Archify generates these through the deliver command.
Step 1: Create a Base Snapshot
Generate a snapshot from your stable branch (typically main or master):
node archify/bin/archify.mjs deliver architecture \
examples/web-app.architecture.json \
./web-app-base.html --json
This produces two artifacts:
web-app-base.html— the visual architecture diagramweb-app-base.json— the validated JSON-IR snapshot used for comparisons
Step 2: Create a Head Snapshot
Generate a second snapshot from your feature branch or proposed changes:
node archify/bin/archify.mjs deliver architecture \
examples/web-app.architecture.json \
./web-app-head.html --json
You now have web-app-base.json and web-app-head.json ready for comparison.
Running the Archify Compare Command
With both snapshots in place, invoke the compare subcommand as documented in [README_EN.md at lines 153-155](https://github.com/tt-a1i/archify/blob/main/README_EN.md#L153-L155):
node archify/bin/archify.mjs compare architecture \
./web-app-base.json ./web-app-head.json \
./web-app-delta.html --json
Command Structure Breakdown
| Position | Argument | Purpose |
|---|---|---|
| 1 | compare |
Subcommand selector parsed by archify/bin/archify.mjs |
| 2 | architecture |
Domain/type of the snapshots being compared |
| 3 | base.json |
Path to the earlier/validated snapshot |
| 4 | head.json |
Path to the newer/proposed snapshot |
| 5 | output.html |
Destination for the visual delta report |
| 6 | --json |
Optional flag to also emit a machine-readable receipt |
Understanding the Delta Engine Internals
The comparison logic lives in archify/delta/architecture-delta.mjs. This module performs three sequential operations:
- Structural diff — Parses both JSON-IR files and builds an internal graph representation of nodes, edges, and properties
- Classification — Categorizes each difference as
added,removed,changed,moved, orreroutedbased on node ID stability and relationship preservation - Rendering — Generates the HTML visualization and assembles the JSON receipt with full diagnostic details
The algorithm is deterministic: identical inputs always produce identical outputs, byte-for-byte. This property is verified by archify/test/architecture-delta.test.mjs, which gates releases against nondeterminism regressions.
Working with Delta Outputs
Visual HTML Report
The architecture-delta.html file presents an interactive view where:
- Green indicates added components
- Red indicates removed components
- Yellow indicates modified properties or relationships
- Blue arrows show rerouted dependencies
The visualization preserves the spatial layout from both source diagrams, making it immediately obvious where changes occurred in the architecture.
JSON Receipt for Automation
When --json is passed, Archify writes a structured receipt suitable for CI integration:
{
"deltas": [
{
"type": "added",
"nodeId": "service-payment-gateway-v2",
"parentId": "bounded-context-payments",
"properties": { ... }
},
{
"type": "rerouted",
"edgeId": "call-auth-to-users",
"oldTarget": "user-service-v1",
"newTarget": "user-service-v2"
}
],
"diagnostics": [
{ "code": "DELTA-001", "severity": "info", "message": "3 nodes added" }
]
}
Programmatic Receipt Processing
Parse the JSON receipt in Node.js to enforce merge policies:
import fs from 'node:fs';
const receipt = JSON.parse(fs.readFileSync('./web-app-delta.json', 'utf8'));
// Gate merge on change type eligibility
const blockedTypes = new Set(['removed', 'rerouted']);
const violations = receipt.deltas.filter(d => blockedTypes.has(d.type));
if (violations.length > 0) {
console.error('❌ Merge blocked: architecture contains breaking changes');
for (const v of violations) {
console.error(` - ${v.type}: ${v.nodeId || v.edgeId}`);
}
process.exit(1);
}
console.log('✅ All changes are additive or non-breaking');
Integrating Archify Compare into CI Pipelines
The deterministic nature of Archify's delta engine makes it ideal for automated checks. A typical GitHub Actions workflow:
- name: Generate base snapshot
run: node archify/bin/archify.mjs deliver architecture main.arch.json base.html --json
- name: Generate head snapshot
run: node archify/bin/archify.mjs deliver architecture pr.arch.json head.html --json
- name: Compare architecture snapshots
run: |
node archify/bin/archify.mjs compare architecture \
base.json head.json \
delta.html --json
- name: Upload delta report
uses: actions/upload-artifact@v4
with:
name: architecture-delta
path: delta.html
Because the output is deterministic, you can additionally cache validation results and diff against previous builds without false positives.
Key Files Reference
| File | Role in Comparison Workflow |
|---|---|
archify/bin/archify.mjs |
CLI entry point; parses compare subcommand and routes to delta engine |
archify/delta/architecture-delta.mjs |
Core delta computation and rendering logic |
archify/test/architecture-delta.test.mjs |
Test coverage for deterministic output and correct classification |
README_EN.md |
Official usage documentation (lines 153-155) |
Summary
- The
comparecommand inarchify/bin/archify.mjsis the primary interface for snapshot comparison - Two validated JSON-IR snapshots (base and head) are required inputs
- Output includes an interactive HTML report and optional JSON receipt via
--json - Delta engine at
archify/delta/architecture-delta.mjsguarantees deterministic, replayable results - Classification covers five change types: added, removed, changed, moved, and rerouted
- CI integration is straightforward due to deterministic output and structured JSON receipts
Frequently Asked Questions
What file formats does Archify compare accept?
Archify compares validated JSON-IR snapshots — the .json artifacts produced by archify deliver --json. It does not accept raw .architecture.json source files or unvalidated outputs; these must first pass through the delivery pipeline to ensure schema compliance and normalization.
Can I compare snapshots from different architecture versions?
Yes, provided both snapshots validate against the same underlying schema. The delta engine in architecture-delta.mjs is schema-agnostic at the comparison layer — it diffs the normalized IR structures. However, semantic interpretation of changes (e.g., whether a property rename is breaking) requires human or policy-based review of the generated delta report.
How do I fail a CI build based on specific change types?
Parse the JSON receipt and inspect the deltas array. Each entry has a type field with values like added, removed, changed, moved, or rerouted. Implement your policy logic in any scripting language — the example in this article demonstrates a Node.js approach using a Set of blocked types and process.exit(1) on violations.
Is the HTML delta output customizable?
The current renderer in architecture-delta.melta.mjs produces a standardized visualization using Archify's built-in HTML generator. For custom styling, you would modify the rendering logic in that module or post-process the JSON receipt with your own visualization layer. The deterministic JSON receipt format is stable and documented, making custom renderers straightforward to maintain.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →