C4 Model vs Nodinite Concept Mapping
This page provides a complete side-by-side mapping of the C4 model's terminology and the corresponding Nodinite Repository entities and properties used in C4 Diagrams. Use this reference when the documentation from c4model.com uses different language than what you see in the Nodinite UI.
Different Diagrams, Different Audiences
Terminology note: The C4 model also has a separate Software Architecture Diagramming Maturity Model with five organisational maturity levels (Level 1 Initial → Level 5 Optimising). That maturity model is about how an organisation practices diagramming — it is not the same as the four C4 diagram types described below.
The C4 model is named after four diagram types — Context, Containers, Components, and Code — that each zoom into a different level of detail. The official c4model.com site notes: "you don't need to use all 4 diagram types; only those that add value — the System Context and Container diagrams are sufficient for most software development teams."
Nodinite implements all five supported diagram types:
| Diagram type | Shorthand | What it shows | Who typically benefits | Mapping on this page |
|---|---|---|---|---|
| System Context | L1 | Systems, people, and high-level relationships between them | Executives, product owners, architects | C4 Level 1 Mapping |
| Container | L2 | Applications, services, databases, and their interactions inside a boundary | Platform engineers, solution architects, dev teams | C4 Level 2 Mapping |
| Component | L3 | Internal modules or components inside a container | Developers, tech leads, code reviewers | C4 Level 3 Mapping |
| Deployment | — | Infrastructure nodes, deployment environments, and how containers are placed across them | DevOps, operations, cloud architects | Deployment Mapping |
| Dynamic | — | Runtime interaction sequence for a specific business workflow | Integration teams, technical leads | Dynamic Mapping |
| Code | L4 | Class diagrams and low-level implementation detail | Developers reviewing specific implementations | Outside scope. Obtainable via the Nodinite MCP endpoint. |
C4 Level 1 — Context Diagram Mapping
In a C4 Context diagram you describe who uses the system and what external systems it interacts with.
| C4 Model Term | C4 Notation | Nodinite Entity | Nodinite Property | Notes |
|---|---|---|---|---|
| Person (internal) | Person(alias, "Name", "Desc") |
System | C4Type = Person |
E.g., "Mobile User", "Finance Analyst" — renders blue |
| Person (external) | Person_Ext(alias, "Name", "Desc") |
System | C4Type = PersonExt |
External human actor — renders grey |
| Internal Software System | System(alias, "Name", "Desc") |
System | C4Type = InternalSystem |
Systems you own and operate |
| External Software System | System_Ext(alias, "Name", "Desc") |
System | C4Type = ExternalSystem |
Third-party, SaaS, or partner systems |
| Internal Database System | SystemDb(alias, "Name", "Desc") |
System | C4Type = SystemDb |
Internal system with database shape |
| External Database System | SystemDb_Ext(alias, "Name", "Desc") |
System | C4Type = SystemDbExt |
External system with database shape |
| Internal Queue System | SystemQueue(alias, "Name", "Desc") |
System | C4Type = SystemQueue |
Internal system with queue shape |
| External Queue System | SystemQueue_Ext(alias, "Name", "Desc") |
System | C4Type = SystemQueueExt |
External system with queue shape |
| Relationship / Interaction | Rel(from, to, "Label", "Tech") |
C4DiagramConnectors | Label + Protocol columns |
Directional arrow with label and technology |
| Bidirectional Relationship | BiRel(from, to, "Label", "Tech") |
C4DiagramConnectors | Label + Protocol + IsBidirectional |
Arrow in both directions |
| System Boundary | Implicit boundary around Internal Systems | Defined per-diagram by boundary presence | — | Internal systems form the "box" |
C4Type Values at a Glance
C4Type |
Value | C4 Term | Mermaid emitted | Colour | |
|---|---|---|---|---|---|
InternalSystem |
1 | Software System (internal) | System(...) |
Blue | |
ExternalSystem |
2 | Software System (external) | System_Ext(...) |
Grey | + overlay |
Person |
3 | Person (internal) | Person(...) |
Blue | |
PersonExt |
4 | Person (external) | Person_Ext(...) |
Grey | + overlay |
SystemDb |
5 | Database system (internal) | SystemDb(...) |
Blue | |
SystemDbExt |
6 | Database system (external) | SystemDb_Ext(...) |
Grey | + overlay |
SystemQueue |
7 | Queue system (internal) | SystemQueue(...) |
Blue | |
SystemQueueExt |
8 | Queue system (external) | SystemQueue_Ext(...) |
Grey | + overlay |
None |
0 | (not in C4 diagram) | (not emitted) | — | — |
Blue vs grey, and the external overlay: Internal variants render blue; external variants render grey. External variants also carry a icon overlay at the top-right corner so they are distinguishable without relying on colour alone — WCAG-compliant in greyscale and high-contrast environments. Note:
is reserved exclusively for theEnterprise_Boundaryshape;ExternalSystemuseswith the external overlay.
C4 Level 2 — Container Diagram Mapping
In a C4 Container diagram you zoom into a system boundary and show its internal containers — the applications, services, databases, and message buses. In Nodinite, a Container node can bind to either a Service or a System depending on what entity best represents the architectural element:
| C4 Model Term | C4 Notation | Nodinite Entity | Nodinite Property | Notes |
|---|---|---|---|---|
| Container | Container(alias, "Name", "Tech", "Desc") |
Service | C4ContainerType + C4Technology |
REST APIs, Databases, Message Buses, Web Apps, etc. |
| Container (platform/portal/tool) | Container(alias, "Name", "Tech", "Desc") |
System | C4Type existing value |
When the architectural element is a platform or portal better modelled as a System |
| Enterprise Boundary | Enterprise_Boundary(alias, "Name") { } |
Domain (optional link) | BoundaryType = EnterpriseBoundary |
Outermost organisational wrapper; DomainId nullable |
| System Boundary | System_Boundary(alias, "Name") { } |
Domain (optional link) | BoundaryType = SystemBoundary |
Single system's boundary; DomainId nullable |
| Generic Boundary | Boundary(alias, "Name", "type") { } |
Domain (optional link) | BoundaryType = Boundary |
Custom/generic grouping; DomainId nullable |
| Container Boundary | Container_Boundary(alias, "Name") { } |
Domain (optional link) | BoundaryType = ContainerBoundary |
Container-level boundary; default for L2 diagrams; DomainId nullable |
| Nested Boundary | Boundary inside a boundary | Domain (optional link) | Parent boundary set during import | Nesting resolved during import wizard; per-diagram |
| Actor inside boundary | System(...) inside a Boundary { } block |
System | Placed in a boundary block during import | Systems can be assigned to a boundary block, not just the top level |
| Person | Person(...) / Person_Ext(...) |
System | C4Type = Person / PersonExt |
Same as L1 |
| External System | System_Ext(...) |
System | C4Type = ExternalSystem |
Same as L1 |
| Relationship | Rel(from, to, "Label", "Tech") |
C4DiagramLinks | Label + Protocol |
Same as L1 |
| Bidirectional Relationship | BiRel(from, to, "Label", "Tech") |
C4DiagramLinks | Label + Protocol + IsBidirectional |
Same as L1 |
| Person Role subtitle | Subtitle text under Person shape | System | C4PersonRole |
E.g., "Customer", "IT Administrator" |
| Technology label | Second parameter $techn in Container(...) |
Service or System | C4Technology |
E.g., "ASP.NET Core", "SQL Server" |
Container → System binding is the key capability that enables platforms, portals, and tools to appear in L2 diagrams correctly without duplicate Service entities.
C4ElementKindon the node controls the rendering shape (container rectangle, database cylinder, etc.) independently of whether the entity is a Service or a System.
C4ContainerType Values at a Glance
C4ContainerType |
Value | C4 Container shape | Example Services | |
|---|---|---|---|---|
None |
0 | Generic container (unspecified) | Catch-all for other types | |
WebApp |
1 | Web application / SPA | Customer Portal, Admin UI | |
MobileApp |
2 | Mobile front-end | iOS App, Android App | |
API |
3 | Web API / REST / gRPC | Customer API, Order Service | |
Database |
4 | Database / datastore | Customer DB, Order DB | |
MessageBus |
5 | Message bus / queue / broker | Azure Service Bus, RabbitMQ | |
Microservice |
6 | Microservice | Shipping Service, Auth Service | |
Function |
7 | Serverless function | Nightly Sync, Azure Function | |
EventStream |
8 | Event stream | Kafka Topic, Event Hub | |
FileStore |
9 | File store / blob storage | Azure Blob, SFTP Folder |
C4 Level 3 — Component Diagram Mapping
In a C4 Component diagram you zoom into a single Container (Service) and show its internal components — the building blocks that together make up that service. This level is intended for developer audiences who need to understand how a specific service is structured.
| C4 Model Term | C4 Notation | Nodinite Entity | Nodinite Property | Notes |
|---|---|---|---|---|
| Component | Component(alias, "Name", "Tech", "Desc") |
Integration | C4ComponentKind |
The logical components inside a Service |
| Container Boundary | Boundary(alias, "Name") { } |
Service | Acts as the enclosing boundary | The parent Service forms the boundary |
| Relationship | Rel(from, to, "Label", "Tech") |
C4DiagramConnectors | Label + Protocol |
Same as L1 and L2 |
| Person | Person(...) |
System | C4Type = Person |
Same as L1 |
| External System | System_Ext(...) |
System | C4Type = ExternalSystem |
Same as L1 |
C4 Deployment Diagram Mapping
A Deployment diagram shows where containers are physically hosted — cloud regions, VNets, servers, on-premises zones. In Nodinite, infrastructure groupings are modelled as Domain boundaries with C4BoundaryType = DeploymentNode.
| C4 Model Term | C4 Notation | Nodinite Entity | Nodinite Property | Notes |
|---|---|---|---|---|
| Deployment Node | Deployment_Node(alias, "Name", "Tech") { } |
Domain boundary | C4BoundaryType = DeploymentNode |
Represents a server, cloud region, VNet, or any infrastructure envelope |
| Nested Deployment Node | Deployment_Node inside another |
Domain boundary | Parent boundary set in designer | Nesting is per-diagram; does not affect global Domain structure |
| Container inside node | Container(alias, "Name", "Tech") |
Service | Same as L2 | Services placed inside Deployment_Node boundaries |
| Relationship | Rel(from, to, "Label", "Tech") |
Connector | Label + Protocol | Same as all other types |
Deployment boundary types are persisted per boundary — imported
C4Deploymentdiagrams retain their infrastructure groupings and the generator re-emits correctDeployment_Node(...)blocks.
C4 Dynamic Diagram Mapping
A Dynamic diagram shows the runtime interaction sequence for a specific business scenario. The key difference from other types is that relationships carry a step order — the numbered sequence of interactions.
| C4 Model Term | C4 Notation | Nodinite Entity | Nodinite Property | Notes |
|---|---|---|---|---|
| Person | Person(alias, "Name") |
System | C4Type = Person |
Same as L1 |
| Container | Container(alias, "Name") |
Service (and Contract in grouped runtime when UseContracts=true) |
Same as L2 for authored diagrams | Dynamic focuses on sequence; grouped runtime can classify a single resolved contract as the participant |
| Ordered relationship | Rel(from, to, "N. Label") |
Connector | Label with parsed step order | The numeric prefix (e.g., 1., 2.) is parsed on import, persisted as sequence order, and re-emitted by the generator |
The full numbered sequence is preserved end-to-end: import → persist → regenerate produces identical step-numbered labels without manual correction.
This mapping describes authored Dynamic diagrams inside Diagram Sets. Grouped Log View runtime inspection is a separate view and can present the same runtime path in Participants mode or Systems mode.
In grouped runtime inspection with
UseContracts=true, a single resolved Contract can be selected as the participant and its owning System is used for Systems-mode boundary placement.
Domain Boundaries — Per-Diagram, Not Global
A key difference between C4 model boundaries and Nodinite Domains:
| C4 Model | Nodinite Implementation | |
|---|---|---|
| Boundary definition | Defined per diagram with arbitrary text labels | Reuses existing Domains from the Repository — no new entities |
| Ordering | Defined by the order they appear in the diagram file | C4DiagramLanes.LaneOrder column — per-diagram, not a global Domain property |
| Boundary type | Different macros (Enterprise_Boundary, System_Boundary, etc.) |
C4BoundaryType set per boundary in the designer — per-diagram, not a global Domain property |
| Nesting | Boundaries can be nested inside other boundaries | A Domain boundary can have a parent boundary in the same diagram — nesting is per-diagram |
| Reuse | A boundary label is just text; not reusable | A Domain can appear in multiple C4 diagrams with different boundary orders, boundary types, and nesting |
This means: reordering, reclassifying, or nesting Domains in one C4 diagram does NOT affect the Domain's position or appearance in the BPM designer or any other C4 diagram. All boundary configuration is always scoped to a specific diagram.
Boundary Type Values at a Glance
C4BoundaryType |
Mermaid emitted | Typical use |
|---|---|---|
ContainerBoundary (default) |
Container_Boundary(...) |
L2 Container diagrams — system containing services |
SystemBoundary |
System_Boundary(...) |
L1 Context diagrams — a single system's boundary |
EnterpriseBoundary |
Enterprise_Boundary(...) |
L1 Context diagrams — the outermost organisation wrapper |
Boundary |
Boundary(...) |
Generic grouping with custom type hint |
DeploymentNode |
Deployment_Node(...) |
Deployment diagrams — infrastructure nodes (servers, cloud regions, VNets) |
Connector / Relationship Mapping
| C4 Model | Nodinite C4 Diagram | Notes |
|---|---|---|
Rel(from, to, "Label") |
Connector with label | Directional arrow from source to target |
Rel(from, to, "Label", "Tech") |
Connector with label and protocol | Protocol maps to C4 $techn |
BiRel(from, to, "Label") |
Bidirectional connector | Arrow rendered in both directions |
BiRel(from, to, "Label", "Tech") |
Bidirectional connector with protocol | Bidirectional with technology label |
Rel(from, to, "N. Label") (Dynamic) |
Ordered connector with step number | The leading numeric prefix (e.g., 1.) is parsed as sequence order on import and re-emitted by the generator — ordering is preserved through the full round-trip |
Properties Added to Existing Entities
C4 Diagrams required adding a small set of new properties to existing Nodinite Repository entities. These are global properties — they are not per-diagram and will appear across the product wherever those entities are used.
New Properties on System
| Property | Type | Purpose | C4 concept |
|---|---|---|---|
C4Type |
Enum | Classifies the System's role in C4 diagrams | Person / InternalSystem / ExternalSystem |
C4PersonRole |
string | Subtitle shown under Person-type nodes | C4 Person description |
C4PositionHint |
Enum | Default placement hint (Top / Bottom) | Actor position relative to boundary stack |
New Properties on Service
| Property | Type | Purpose | C4 concept |
|---|---|---|---|
C4ContainerType |
Enum | Classifies the Service as a C4 Container type | Container (API, Database, MessageBus, etc.) |
C4Technology |
string | Technology stack / platform label | C4 $techn parameter in Container(...) |
New Properties on Domain
| Property | Type | Purpose | C4 concept |
|---|---|---|---|
DefaultBoundaryType |
Enum (nullable) | Default boundary macro to seed when this Domain is first placed in a new diagram | Container_Boundary, System_Boundary, Enterprise_Boundary, Boundary, Deployment_Node |
DefaultTypeLabel |
string (nullable) | Default type-hint label seeded into new boundaries (e.g., "Azure Region") |
C4 $type parameter in Boundary(...) / Deployment_Node(...) |
New Properties on Integration
| Property | Type | Purpose | C4 concept |
|---|---|---|---|
C4ComponentKind |
Enum (nullable) | Classifies the Integration's C4 component shape — Component, ComponentDb, or ComponentQueue |
C4 Component shape |
C4Technology |
string (nullable) | Technology stack label seeded into new L3 component nodes | C4 $techn parameter in Component(...) |
What Is NOT Changed
The following entities and tables are completely unchanged in the C4 Diagrams feature:
| Entity / Table | Why unchanged |
|---|---|
BPMs, BPMLanes, BPMPhases, BPMServices, BPMConnectors |
C4 Diagrams is entirely additive — BPM tables are not touched |
Domains global ordering |
Domain boundary ordering is per-diagram via C4DiagramLanes.LaneOrder, not a Domain-level column |
TransportContracts, MessageTypes, Endpoints |
Contract entities remain scoped to Services; authored-diagram import behavior is unchanged |
| Existing "Show in Mermaid" rendering on Integrations/Services | Continues to work as-is; C4 Diagram Mermaid View is a separate output |
Frequently Asked Questions
Why is the C4 "System" mapped to Nodinite "System" but the names look different?
In pure C4 model language, "System" means a top-level software system containing many containers. In Nodinite, the System entity represents any software product, organization, or platform — which maps naturally to C4's external actors (Person, ExternalSystem). The Service entity holds the detailed container-level information (what the system runs, how it communicates), which maps to C4 Container.
Can I use a Domain as a C4 "System Boundary" (the dotted box)?
Yes, but a Domain link is optional. During the import wizard, each Boundary(...) block in your Mermaid markup presents a choice: link it to an existing Domain in your Repository, or keep it as a label-only boundary. Both are valid. Label-only boundaries are useful for external organisation zones, cloud regions, or partner system groups where no corresponding Domain entity exists.
The boundary type (Container_Boundary, System_Boundary, Enterprise_Boundary, Boundary, Deployment_Node) is detected automatically from the Mermaid macro and stored per boundary element — no manual selection required.
Can I nest boundaries inside other boundaries?
Yes. During the import wizard, boundaries parsed from nested Boundary { } blocks in the Mermaid source are stored with parent–child relationships. The Mermaid output will render the inner boundary as a block nested inside its parent boundary. Nesting is a per-diagram setting — it does not affect the Domain's appearance in the BPM designer or any other C4 diagram.
Can I place a System (actor) inside a boundary?
Yes. During the import wizard, if your Mermaid source has a System(...) or Person(...) element nested inside a Boundary { } block, it is stored as a member of that boundary. The Mermaid output re-emits it inside the boundary block. This is useful for L1 Context diagrams where internal systems sit inside a System_Boundary or Enterprise_Boundary block.
What happens if a Service has no C4ContainerType set?
The Service will appear as a generic None container node in the diagram with no technology-specific icon. The diagram will still render. It is recommended to set C4ContainerType before including a Service in a C4 diagram for accurate notation.
Can I have the same Service appear under two different Domains in the same diagram?
Yes. This matches the existing many-to-many relationship between Services and Domains in the Repository (same model used by BPM). A non-blocking warning is shown when you drag a Service into a second boundary in the same diagram, but the insert succeeds.