archidoc
Your architecture diagrams are always wrong because nobody updates them. archidoc fixes this — it extracts C4 architecture documentation directly from source code annotations, so your diagrams stay in sync with your code. If they drift, archidoc --check fails your CI build.
What It Does
Developers annotate module entry files (mod.rs, index.ts, __init__.py) with structured comments containing C4 markers, GoF pattern labels, and file-level responsibility tables. archidoc compiles these annotations into a single ARCHITECTURE.md containing:
- Inline Mermaid C4 diagrams (container and component levels)
- Component index table (linking directly to source files)
- Relationship map (dependency arrows with labels and protocols)
- AI context file (
ARCHITECTURE.ai.md) — token-optimized tree format for LLM consumption (~75% fewer tokens) - JSON IR (portable intermediate representation for cross-language pipelines)
Optional sidecar outputs: PlantUML (--plantuml) and draw.io CSV (--drawio). The AI context file is generated by default (suppress with --no-ai).
It also detects architecture drift (docs out of sync with code), validates file tables (ghost/orphan detection), and reports architecture health (pattern confidence, file maturity).
Install
# From crates.io
# Or from source
# Or build locally
# Binary at target/release/archidoc
# TypeScript adapter (npm)
Usage
# Generate ARCHITECTURE.md + ARCHITECTURE.ai.md from source annotations
# Custom output path
# Skip AI context generation
# Also generate PlantUML and/or draw.io sidecar files
# Scaffold root-level lib.rs template for a new project
# Scaffold with explicit language (if auto-detection fails)
# Generate annotation template for a module directory
# Write the template directly into a module entry file
# Check for documentation drift (CI gate — exits non-zero on drift)
# Print architecture health report
# Validate file tables (ghost/orphan detection)
# Export JSON IR for cross-language pipelines
# Generate ARCHITECTURE.md from JSON IR (any language adapter)
# Merge IR from multiple adapters (polyglot projects)
Annotation Convention
Container-level (mod.rs):
//! @c4 container
//!
//! # Bus Module
//!
//! Central messaging and caching backbone.
//!
//! @c4 uses agents_internal "Processed market data" "crossbeam channel"
//!
//! | File | Pattern | Purpose | Health |
//! |------|---------|---------|--------|
//! | `lanes.rs` | Observer | Event routing channels | active |
//! | `store.rs` | Repository | Lock-free cache | stable |
TypeScript (index.ts):
/**
* @c4 container
*
* Central messaging and caching backbone.
*
* @c4 uses agents_internal "Processed market data" "WebSocket"
*
* | File | Pattern | Purpose | Health |
* |------|---------|---------|--------|
* | `core.ts` | Facade | Entry point | stable |
*/
C4 Markers
@c4 container— marks a C4 container@c4 component— marks a C4 component@c4 uses target "label" "protocol"— declares a dependency
File Table
Each row declares a file in the module with its GoF pattern, purpose, and health status:
| Column | Values |
|---|---|
| Pattern | Any GoF pattern name, or -- for none |
| Health | planned (not yet implemented), active (in progress), stable (complete) |
Pattern Confidence
Pattern labels have two tiers:
- planned — developer's stated intent
- verified — structurally confirmed by heuristic analysis (Observer, Strategy, Facade)
Getting Started
Greenfield (new project)
-
Scaffold the root template — generates a
lib.rs/index.tsdoc comment with TODO sections for purpose, C4 context, data flow, concurrency patterns, deployment, and external dependencies:Paste the output into your root entry file (
lib.rsorindex.ts) and fill in the TODOs. -
Add module annotations — as you create modules, scaffold their annotations:
-
Generate docs:
This produces
ARCHITECTURE.md(human-readable) andARCHITECTURE.ai.md(token-optimized for LLMs).
Brownfield (existing project)
-
Pick your top-level modules — identify the 3-5 directories that represent your system's major containers (e.g.
api/,core/,database/) -
Scaffold annotations for each module:
-
Add a C4 marker to each module's entry file (
mod.rs,index.ts, or__init__.py)://! @c4 container //! //! # Api //! //! REST API gateway — handles authentication and request routing. -
Run archidoc to generate your first diagrams:
-
Optionally scaffold the root — if you want data flow, concurrency, and deployment sections in your docs:
-
Add relationships between containers:
//! @c4 uses database "Persists user data" "sqlx" -
Gate your CI to prevent architecture drift:
Start with containers only. Add components, file tables, and relationships as the architecture stabilizes. See Annotating Your Project for the full step-by-step guide.
Project Structure
Cargo.toml Workspace root
core/
archidoc-types/ Shared types (ModuleDoc, C4Level, FileEntry, Relationship, etc.)
archidoc-engine/ Language-agnostic generator (ARCHITECTURE.md, ai context, mermaid, plantuml, draw.io, IR, drift, health)
archidoc-cli/ CLI binary: archidoc
spec/ JSON IR schema
tests/ BDD test infrastructure (DSL, protocol drivers, fakes)
adapters/
archidoc-rust/ Rust adapter (//! doc comments -> ModuleDoc)
archidoc-ts/ TypeScript adapter (@c4 JSDoc -> JSON IR)
docs/ Guides (annotation spec, getting started, LLM context)
examples/ Example annotated projects
Architecture
archidoc follows a three-layer architecture:
- Types (
archidoc-types) — shared domain model:ModuleDoc,C4Level,FileEntry,Relationship,PatternStatus,HealthStatus - Adapters (
archidoc-rust,archidoc-ts) — language-specific parsers that extract annotations and emitModuleDocarrays - Engine (
archidoc-engine) — language-agnostic generators that consumeModuleDocand produce ARCHITECTURE.md, diagrams, IR, drift reports, and health summaries
The CLI orchestrates: adapter parses source -> engine generates ARCHITECTURE.md.
JSON IR
The intermediate representation (ModuleDoc[] as JSON) is the contract between adapters and the engine. Any language adapter that emits conforming JSON can use the full engine pipeline. See core/spec/archidoc-ir-schema.json for the schema.
Writing a Language Adapter
To add support for a new language:
- Scaffold with
archidoc init-adapter --lang python - Implement a parser that extracts annotations from your language's comment format
- Implement a walker that traverses source directories and collects
ModuleDocentries - Emit
ModuleDoc[]JSON to stdout — the engine handles the rest
See the archidoc-rust and archidoc-ts adapters for reference implementations.
Tests
# Run all Rust tests
# Run TypeScript adapter tests
&&
The test suite uses Dave Farley-style BDD: declarative test cases specify WHAT (behavior), protocol drivers translate to HOW (implementation). When the implementation changes, update drivers — not tests.
License
MIT