8 C4 Architecture Projections
Quarto-Needs integrates the C4 model (Context, Container, Component, Code) into the canonical engineering graph. Rather than creating architecture diagrams in external drawing tools that drift from requirements, architecture elements are first-class engineering objects connected by typed relations.
8.1 Architecture Elements
C4 elements are authored using standard .need blocks with dedicated types:
| Type | C4 Level | Suggested Prefix | Role |
|---|---|---|---|
system |
Context / Container | SYS- |
architecture-element |
external-system |
Context | EXT- |
architecture-element |
actor |
Context | ACTOR- |
architecture-element |
container |
Container | CONTAINER- |
architecture-element |
component |
Component | COMP- |
architecture-element |
source-module |
Code | SRC- |
implementation-artifact |
deployment-node |
Deployment | DEPLOY- |
architecture-element |
8.2 Hierarchical Relations
C4 diagrams derive structure from two primary relations:
-
part-of: defines structural containment.-
containerispart-ofasystem -
componentispart-ofacontainer -
source-moduleispart-ofacomponent
-
-
depends-on: defines interaction and dependencies between elements. It may carry inline attributes:labeloverrides the relationship description in every diagram, andtechnologyis rendered as the relationship technology where the backend supports it (Rel(..., "label", "technology")in Mermaid and PlantUML; folded into the edge label in D2). -
deployed-on: places an artifact on a deployment node (containerorcomponentisdeployed-onadeployment-node), and nested deployment nodes arepart-oftheir parent node. -
interacts-with: an ordered runtime interaction between two elements for a dynamic view (initiatorisinteracts-withparticipant). Theorderattribute sequences the interactions;labelandtechnologyrender like any other relationship.
Example:
::: {.need #SYS-APP type="system" status="approved"}
## Enterprise Application
Core transaction and management platform.
:::
::: {.need #CONTAINER-API type="container" status="approved" technology="FastAPI / Python" part-of="SYS-APP"}
## REST API Container
Handles business logic and external integrations.
:::
::: {.need #COMP-AUTH type="component" status="implemented" part-of="CONTAINER-API"}
## Authentication Service
Validates bearer tokens and enforces permissions.
:::8.3 Modeling cookbook
8.3.1 Modeling a deployment
Declare one deployment-node per place things run, put nested nodes part-of their parent, and place each artifact on a node with deployed-on:
::: {.need #DEPLOY-PROD type="deployment-node" status="approved" environment="production"}
## Production
The managed runtime that serves the containers.
:::
::: {.need #CONTAINER-API type="container" status="approved" technology="FastAPI / Python" part-of="SYS-APP" deployed-on="DEPLOY-PROD"}
## REST API Container
:::{{< need-c4 root="DEPLOY-PROD" level="deployment" >}}level="deployment" requires a deployment-node focus. The view draws the node’s boundary with its nested nodes and the containers/components deployed on it; an artifact with no deployed-on edge is simply not shown. deployed-on is the authoring direction (artifact → node); deploys is its accepted inverse. Mermaid renders C4Deployment, PlantUML includes C4_Deployment, Structurizr uses a deploymentEnvironment, and D2 nests packages.
8.3.2 Modeling a dynamic scenario
Order runtime interactions with interacts-with and an order attribute; label and technology render like any other relationship:
::: {.need #ACTOR-ENGINEER type="actor" status="approved" interacts-with='CONTAINER-WEB order="1" label="submits a request"'}
## Engineer
:::
::: {.need #CONTAINER-WEB type="container" status="approved" technology="React" part-of="SYS-APP" interacts-with='CONTAINER-API order="2" label="calls the API" technology="HTTPS/JSON"'}
## Web Application
:::{{< need-c4 root="SYS-APP" level="dynamic" >}}level="dynamic" requires a system focus. Participants are the focus, its direct containers, and every interaction partner of that set — an interaction between two containers is drawn even though neither touches the system directly. Interactions are numbered by order (un-ordered edges sort last, deterministically). Mermaid renders C4Dynamic with RelIndex, PlantUML a sequence diagram, Structurizr a dynamic view, and D2 a sequence diagram.
8.4 Rendering C4 Diagrams
Use the {{< need-c4 >}} shortcode to render architecture views:
{{< need-c4 root="SYS-APP" level="context" >}}
{{< need-c4 root="SYS-APP" level="container" >}}
{{< need-c4 root="CONTAINER-API" level="component" >}}
{{< need-c4 root="COMP-AUTH" level="code" >}}
{{< need-c4 root="DEPLOY-PROD" level="deployment" >}}
{{< need-c4 root="SYS-APP" level="dynamic" >}}8.4.1 Supported Levels
-
context: Focuses on asystemand its interactions withactors andexternal-systems. -
container: Zooms into asystemto show its constituentcontainers and external connections. -
component: Zooms into acontainerto reveal internalcomponents and dependencies. -
code: Materializes the implementation surface as a structured Markdown table ofsource-moduleartifacts, file paths, languages, and requirements implemented. -
deployment: Focuses on adeployment-node, showing nested nodes and the artifactsdeployed-onit. -
dynamic: Focuses on asystemand draws its ordered runtime interactions as a numbered sequence (MermaidC4Dynamic, a PlantUML sequence diagram, a Structurizrdynamicview, or a D2 sequence diagram).
8.4.2 Multiple Diagramming Backends
Quarto-Needs supports multiple diagramming backends via the backend argument:
{{< need-c4 root="SYS-APP" level="container" backend="mermaid" >}}
{{< need-c4 root="SYS-APP" level="container" backend="plantuml" >}}
{{< need-c4 root="SYS-APP" level="container" backend="structurizr" >}}
{{< need-c4 root="SYS-APP" level="container" backend="d2" >}}-
mermaid(default): Embedded directly in HTML as responsive inline SVG. -
plantuml,structurizr,d2: If the respective tool is installed locally, pre-renders SVG/PNG assets; otherwise falls back gracefully to syntax-highlighted diagram source code.
Deployment-level PlantUML output includes the C4_Deployment stdlib; a PlantUML old enough to lack that file falls back to source text exactly like a missing backend.
Because that fallback is silent, a publishing pipeline can ship source code where diagrams belong. Run tools/install_diagram_backends.sh to provision all three on Linux; CI runs the same script and then fails the build if any diagram rendered as source.
8.5 Architecture Governance (C4 Rules)
The C4 rule engine validates diagram structural integrity:
| Rule | Check |
|---|---|
C4001 |
In a Container view, every container must declare its parent system via part-of
|
C4002 |
In a Component view, every component must declare its parent container via part-of
|
C4003 |
Inter-element relations must have a descriptive label |
C4004 |
Hierarchy violations (e.g. cyclic containment or orphan boundaries) are rejected |