Shapes and Toolbox Reference
The toolbox panel is the palette of shapes available when building or editing a C4 diagram. Its contents are context-sensitive: only shapes that are valid for the active diagram type are shown. The implementation filters the palette by diagram type, so the visible toolbox is always a subset of the full C4 shape vocabulary.
The same shape vocabulary covers three surfaces in Nodinite, all in exact correspondence:
| Surface | What you do |
|---|---|
| Toolbox | Drag and drop shapes onto the canvas in the designer |
| Canvas | The placed shape renders on the live diagram |
| Import | The same shapes are produced when importing Mermaid, PlantUML, Structurizr DSL, or Draw.io XML into the import wizard |
This means a diagram built by importing external source markup or Draw.io XML will produce the same shape families as one assembled by hand — and diagrams built in the designer will export clean, standards-compliant Mermaid that any C4-aware tool can read.
Toolbox Filter, Resolver, and Binding Defaults
The filter chips above the toolbox do not mean the selected diagram is limited to a single binding target. They filter which repository-centric shape families are emphasized in the toolbox panel, while the node resolver and persistence logic decide what a selected node can bind to and what the default binding kind should be.
| Filter chip | What it emphasizes in the toolbox | What it does not mean |
|---|---|---|
| All | All currently allowed toolbox sections for the diagram type | It does not force every node to bind to every repository entity kind |
| System | System-facing shapes, plus the System-oriented advanced items that are valid in the current diagram | It does not mean every selected node binds as a System |
| Service | Service-facing container and deployment scope items | It does not mean the current node is a Service node |
| Integration | Integration-facing component items | It does not mean the current node is integration-only in the resolver |
| Contract | Contract-capable items where contract support is enabled | It does not mean the diagram type itself is contract-only |
The resolver path is separate. The designer default may prefer Integration, Service, or Contract depending on the node kind and current binding, but the filter chip only changes what is shown in the toolbox, not the binding model itself.
Component Type Icons vs Toolbox Icons
Every shape on the canvas can display one of two kinds of icon:
- Toolbox default icon — the built-in icon for the shape type. This is the icon shown in the toolbox sidebar and is always used as the fallback when no Component Type is available.
- Component Type icon — the icon from the Component Type assigned to the bound Repository entity.
When the bound entity has a Component Type, that icon replaces the toolbox default on the canvas. Assign the icon once to a Repository entity — a System, Service, Integration, or Domain — and it propagates automatically to every C4 diagram that references that entity, in both view mode and the designer.
Important
The entity Component Type always wins. If a System has a Component Type assigned, every node bound to that System shows that CT icon in every diagram — no additional configuration needed per diagram. For the full priority chain and fallback rules see Component Types.
The toolbox icons listed throughout this page are the default fallback icons shown when no Component Type is assigned to the bound entity.
The Internal vs External Icon Convention
Every actor and node shape exists in two variants: internal and external. Nodinite distinguishes these consistently across all diagram types using an icon overlay — colour alone is never the only signal.
| Variant | Icon treatment | Canvas colour | Mermaid macro pattern |
|---|---|---|---|
| Internal | Base icon alone | Blue | No suffix — Person, Container, Component |
| External | Base icon + overlay at the top-right corner | Grey | _Ext suffix — Person_Ext, Container_Ext, Component_Ext |
The same icon pairing is applied at every tier:
| Tier | Internal icon | External icon |
|---|---|---|
| Person / User | + | |
| Software System | + | |
| Container (generic) | + | |
| Database (any tier) | + | |
| Queue / Stream (any tier) | + | |
| Component | + |
Shape Availability by Diagram Type
| Shape | L0 / L1 | L2 | L3 | Dynamic | Deployment |
|---|---|---|---|---|---|
| Person (internal) | ✅ | ✅ | ✅ | ✅ | ❌ |
| Person (external) | ✅ | ✅ | ✅ | ✅ | ❌ |
| Software System | ✅ | ❌ | ❌ | ❌ | ❌ |
| Software System (external) | ✅ | ✅ | ✅ | ✅ | ❌ |
| Database System | ✅ | ❌ | ❌ | ❌ | ❌ |
| Database System (external) | ✅ | ✅ | ❌ | ❌ | ❌ |
| Queue System | ✅ | ❌ | ❌ | ❌ | ❌ |
| Queue System (external) | ✅ | ✅ | ❌ | ❌ | ❌ |
| Container (generic or sub-typed) | ❌ | ✅ | ❌ | ✅ | ❌ |
| Container (external) | ❌ | ✅ | ❌ | ✅ | ❌ |
| Container Instance | ❌ | ✅ | ❌ | ❌ | ✅ |
| Container Instance (external) | ❌ | ✅ | ❌ | ❌ | ✅ |
| Container Database | ❌ | ✅ | ❌ | ✅ | ❌ |
| Container Database (external) | ❌ | ✅ | ❌ | ✅ | ❌ |
| Container Queue / Stream | ❌ | ✅ | ❌ | ✅ | ❌ |
| Container Queue (external) | ❌ | ✅ | ❌ | ✅ | ❌ |
| Component | ❌ | ❌ | ✅ | ❌ | ❌ |
| Component (external) | ❌ | ❌ | ✅ | ❌ | ❌ |
| Component Database | ❌ | ❌ | ✅ | ❌ | ❌ |
| Component Database (external) | ❌ | ❌ | ✅ | ❌ | ❌ |
| Component Queue | ❌ | ❌ | ✅ | ❌ | ❌ |
| Component Queue (external) | ❌ | ❌ | ✅ | ❌ | ❌ |
| Infrastructure Node | ❌ | ❌ | ❌ | ❌ | ✅ |
| Container Boundary | ❌ | ✅ | ✅ | ❌ | ❌ |
| System Boundary | ✅ | ✅ | ❌ | ❌ | ❌ |
| Enterprise Boundary | ✅ | ✅ | ❌ | ❌ | ❌ |
| Generic Boundary | ✅ | ✅ | ❌ | ❌ | ❌ |
| Deployment Node | ❌ | ❌ | ❌ | ❌ | ✅ |
| Relationship — solid | ✅ | ✅ | ✅ | ✅ | ✅ |
| Relationship — async (dashed) | ✅ | ✅ | ✅ | ✅ | ✅ |
| Bidirectional ↔ | ✅ | ✅ | ✅ | ❌ | ❌ |
| Numbered Step | ❌ | ❌ | ❌ | ✅ | ❌ |
| Numbered Step (Async) | ❌ | ❌ | ❌ | ✅ | ❌ |
| Return / Callback | ❌ | ❌ | ❌ | ✅ | ❌ |
Note
In Dynamic diagrams the standard Relationship shapes gain a step-number badge, and a dedicated Return ← (
Rel_Back) connector is added. Bidirectional (BiRel) is accepted on import for Dynamic diagrams but is not exposed as a primary toolbox shape.
L0 System Landscape and L1 System Context
L0 and L1 use the same Mermaid C4Context declaration and identical toolbox sections. The distinction is conceptual: L0 spans your full enterprise landscape; L1 focuses on a single system in its context.
The filter chips on these diagrams emphasize System-facing repository scopes, but the selected shape still resolves according to the node's actual binding/default state. In practice, the toolbox shows the actor and system families that are valid for the current diagram, while the resolver decides whether a selected node is an unbound System placeholder, a bound System entity, or an external variant.
L0/L1 Toolbox Sections
Persons → Systems → Connectors
Person Shapes
| Shape | Icon | Mermaid Macro | Nodinite Entity | Notes |
|---|---|---|---|---|
| Person | Person |
System — C4Type = Person |
Internal user, analyst, or role | |
| Person (external) | + | Person_Ext |
System — C4Type = PersonExt |
External customer, trading partner, or user |
System Shapes
| Shape | Icon | Mermaid Macro | Nodinite Entity | Notes |
|---|---|---|---|---|
| Software System | System |
System — C4Type = InternalSystem |
A system you own and operate | |
| Software System (external) | + | System_Ext |
System — C4Type = ExternalSystem |
Third-party, SaaS, or partner system |
| Database System | SystemDb |
System — C4Type = SystemDb |
Internal system rendered as a database cylinder | |
| Database System (external) | + | SystemDb_Ext |
System — C4Type = SystemDbExt |
External database system |
| Queue System | SystemQueue |
System — C4Type = SystemQueue |
Internal message bus or queue at context level | |
| Queue System (external) | + | SystemQueue_Ext |
System — C4Type = SystemQueueExt |
External queue, event bus, or stream |
Note
For L0/L1, the System filter is the one that maps most directly to the repository binding model. It does not change the diagram type, but it does help the resolver/editor focus on the System entity family and its external variants.
Boundary Shapes (L0/L1)
| Shape | Icon | Mermaid Macro | Notes |
|---|---|---|---|
| System Boundary | System_Boundary |
Marks a single system's scope | |
| Enterprise Boundary | Enterprise_Boundary |
Outermost organisational wrapper | |
| Generic Boundary | Boundary |
Custom grouping with a free-text type hint |
L2 Container Diagram
Container diagrams zoom inside a system boundary to show the applications, services, databases, and message buses that implement it. Container nodes bind to Service entities; platforms, portals, and tools may bind to System entities when that entity better represents the architectural element.
The filter chips on L2 are more nuanced than a simple Service-only view: the toolbox can surface Service, System, Integration, and Contract-oriented choices depending on what is valid for the current diagram and what the selected node can actually resolve to. The filter affects what is shown; the resolver determines whether the node lands on a Service binding, a Contract binding, or stays unbound.
L2 Toolbox Sections
Persons → Containers → Databases → Queues & Streams → External Systems → External Containers → Boundaries → Connectors
Container Sub-Types
| Shape | Icon | Mermaid Macro | C4ContainerType |
Example |
|---|---|---|---|---|
| Container (generic) | Container |
None |
Catch-all; use when no specific sub-type applies | |
| Web Application | Container |
WebApp |
Customer portal, admin UI, single-page app | |
| Mobile App | Container |
MobileApp |
iOS app, Android app | |
| REST API / Service | Container |
API |
Customer API, Order Service, gRPC endpoint | |
| Microservice | Container |
Microservice |
Shipping service, auth service | |
| Serverless / Function | Container |
Function |
Azure Function, AWS Lambda, nightly batch | |
| File Store | Container |
FileStore |
Azure Blob, SFTP folder, NFS mount | |
| Container (external) | + | Container_Ext |
— | External container inside scope |
| Container Instance | Container_Instance |
— | A specific running replica of a container |
Database Shapes (L2)
| Shape | Icon | Mermaid Macro | C4ContainerType |
Notes |
|---|---|---|---|---|
| Database / Datastore | ContainerDb |
Database |
SQL Server, PostgreSQL, MongoDB, Cosmos DB | |
| Cache / Key-Value Store | ContainerDb |
Cache |
Redis, Memcached | |
| Database (external) | + | ContainerDb_Ext |
— | External database accessed by the system |
Queue and Stream Shapes (L2)
| Shape | Icon | Mermaid Macro | C4ContainerType |
Notes |
|---|---|---|---|---|
| Message Bus / Queue | ContainerQueue |
MessageBus |
Azure Service Bus, RabbitMQ, SQS | |
| Event Stream | ContainerQueue |
EventStream |
Kafka topic, Azure Event Hub | |
| Queue / Stream (external) | + | ContainerQueue_Ext |
— | External queue or stream outside the boundary |
External System Shapes (L2)
| Shape | Icon | Mermaid Macro | Nodinite Entity | Notes |
|---|---|---|---|---|
| Software System (external) | + | System_Ext |
System — C4Type = ExternalSystem |
Third-party or partner system |
| Database System (external) | + | SystemDb_Ext |
System — C4Type = SystemDbExt |
External database at system tier |
| Queue System (external) | + | SystemQueue_Ext |
System — C4Type = SystemQueueExt |
External queue or event bus at system tier |
Note
If the System filter is selected on an L2 diagram, the toolbox is simply surfacing the System-facing items that are valid in a container context. That does not mean the node being edited becomes a System binding; container and service nodes still resolve through the binding picker and persistence defaults.
Boundary Shapes (L2)
| Shape | Icon | Mermaid Macro | Notes |
|---|---|---|---|
| Container Boundary | Container_Boundary |
Default boundary at L2 | |
| System Boundary | System_Boundary |
Single system's boundary within an enterprise view | |
| Enterprise Boundary | Enterprise_Boundary |
Outermost organisational wrapper | |
| Generic Boundary | Boundary |
Custom grouping with a free-text type hint |
L3 Component Diagram
Component diagrams zoom into a single Service scope and show its internal building blocks. The visible toolbox can be filtered to System, Service, Integration, or Contract, but that filter is not the same thing as the node's binding target. Component nodes can bind to Integration, Service, or [Contract][Contracts] entities in the Repository, depending on the selected node binding kind and permissions.
For L3, the important split is between what the filter surfaces and what the component resolver can actually bind. The System filter exposes the valid advanced System shapes, while the binding picker still allows Integration, Service, or Contract defaults depending on the selected node kind.
The toolbox sections are:
Components → External Actors → Boundaries → Connectors → Advanced (collapsed)
Component Shapes
| Shape | Icon | Mermaid Macro | Nodinite Entity | Notes |
|---|---|---|---|---|
| Component | Component |
Integration / Service / [Contract][Contracts] — C4ComponentType = None |
Generic logical building block | |
| Component (external) | + | Component_Ext |
Integration / Service / [Contract][Contracts] (optional binding) | External module or third-party library |
| Component Database | ComponentDb |
Integration / Service / [Contract][Contracts] — C4ComponentType = Repository |
Data access component | |
| Component Database (external) | + | ComponentDb_Ext |
Integration / Service / [Contract][Contracts] (optional binding) | External data store accessed by this component |
| Component Queue | ComponentQueue |
Integration / Service / [Contract][Contracts] — C4ComponentType = Queue |
Async message consumer or producer | |
| Component Queue (external) | + | ComponentQueue_Ext |
Integration / Service / [Contract][Contracts] (optional binding) | External queue or stream |
Note
The designer defaults a component node to Integration, but the binding picker and persistence helpers allow Service and Contract bindings as well. The implementation should keep those options visible in the doc so the page matches what the UI and resolver can actually do.
External Actor Shapes (L3)
The same Person and Software System (external) shapes from L0/L1 are available at L3, placed outside the Container Boundary that encloses the component hierarchy.
Note
When the System filter is selected on a Component diagram, the toolbox shows the System-facing L3 items that remain valid in the current diagram type. Those shapes are not the same thing as the node's repository binding target; the selected node may still resolve as Integration, Service, or Contract depending on its binding/default state.
Advanced System Shapes (L3)
The collapsed Advanced section exposes the System-level shapes that are still valid in a Component diagram:
| Shape | Icon | Mermaid Macro | Notes |
|---|---|---|---|
| Software System | System |
Advanced System-level shape available in L3 | |
| Database System | SystemDb |
Advanced System-level shape available in L3 | |
| Database System (external) | + | SystemDb_Ext |
Advanced System-level shape available in L3 |
| Queue System | SystemQueue |
Advanced System-level shape available in L3 | |
| Queue System (external) | + | SystemQueue_Ext |
Advanced System-level shape available in L3 |
Note
The System filter in a Component diagram is about availability, not ownership. It exposes the advanced System shapes because they are valid toolbox items at L3, but the selected node's repository binding is still decided separately.
Boundary Shapes (L3)
| Shape | Icon | Mermaid Macro | Notes |
|---|---|---|---|
| Container Boundary | Container_Boundary |
Pre-placed as the scope Container; encloses all Component nodes |
Dynamic Diagram
Dynamic diagrams show the runtime interaction sequence for a specific business workflow. Participants are Container or Person instances; connectors carry step numbers to define the execution order. There is no Boundaries section in the Dynamic toolbox.
Dynamic diagrams are participant-first. The filter chips are still relevant because they change which participant families are shown, but the selection model is sequence-oriented rather than repository-binding-oriented. In other words, the toolbox filters the participant palette, while the diagram state keeps the focus on ordered runtime interaction rather than a System/Service/Integration bind decision.
Dynamic Toolbox Sections
Participants → Connectors
Participant Shapes (Dynamic)
| Shape | Icon | Mermaid Macro | Notes |
|---|---|---|---|
| Person | Person |
Internal role in the sequence | |
| Person (external) | + | Person_Ext |
External actor in the sequence |
| Container (any sub-type) | Container |
Participating service; technology subtitle is optional at this level | |
| Container Database | ContainerDb |
Database participant | |
| Container Queue | ContainerQueue |
Message queue participant | |
| Software System (external) | + | System_Ext |
External system in the interaction flow |
Note
The Dynamic toolbox should be read as "these participant types are valid in a sequence diagram", not as a repository binding matrix. The filter changes the visible participant families; the step/return connector model is what gives the diagram its shape.
Connector Shapes (Dynamic)
| Shape | Icon | Mermaid Macro | Notes |
|---|---|---|---|
| Numbered Step | Rel with step prefix |
Standard synchronous call | |
| Numbered Step (Async) | (dashed badge) | Rel dashed with step prefix |
Asynchronous or fire-and-forget delivery |
| Return/Callback | Rel_Back |
Response arrow; source and target keep their logical order |
Deployment Diagram
Deployment diagrams show where container instances are physically hosted — infrastructure nodes and container instances. There is no Persons section and no System-level section in the Deployment toolbox.
Deployment is also filter-driven, but here the filter is mainly separating infrastructure participants from the rest of the C4 vocabulary. The visible shapes are Infrastructure Node and Container Instance families; the selected node is resolved according to the deployment-specific item you place, not by a generic System/Service binding.
Deployment Toolbox Sections
Infrastructure Nodes → Container Instances → Connectors
Infrastructure Node Shapes
| Shape | Icon | Mermaid Macro | Notes |
|---|---|---|---|
| Infrastructure Node | InfrastructureNode |
Generic deployment participant exposed in the toolbox | |
| Deployment Node | Deployment_Node |
Deployment boundary / infrastructure envelope |
Deployment Participants
| Shape | Icon | Mermaid Macro | Notes |
|---|---|---|---|
| Container Instance | Container_Instance |
Specific running replica; binds to the same Service as its base Container | |
| Container Instance (external) | + | Container_Instance_Ext |
External or managed instance outside the local deployment boundary |
Note
If you are looking at a Deployment diagram and switch the filter, you are changing the visible deployment vocabulary, not the meaning of the selected node. The binding/default logic remains separate from the toolbox filter.
Boundaries
Boundaries group nodes inside a dashed labelled box. They optionally link to a Domain entity, but a label-only boundary with no Repository anchor is also valid.
Important
Boundaries are per-diagram, not global. Placing a Domain inside a boundary in one C4 diagram — or changing its boundary type, nesting, or order — does not affect where that Domain appears in any other diagram or in the BPM Designer. All boundary configuration is scoped to the specific diagram.
| Boundary Shape | Icon | Mermaid Macro | Available In | Notes |
|---|---|---|---|---|
| Container Boundary | Container_Boundary |
L2, L3 | Default boundary at L2; also used at L3 as the scope Container wrapper | |
| System Boundary | System_Boundary |
L0/L1, L2 | A single system's boundary within a wider view | |
| Enterprise Boundary | Enterprise_Boundary |
L0/L1, L2 | Outermost organisational wrapper | |
| Generic Boundary | Boundary |
L0/L1, L2 | Custom grouping with a free-text type hint | |
| Deployment Node | Deployment_Node |
Deployment | Infrastructure zone; supports unlimited nesting |
Connectors
The toolbox exposes a diagram-specific connector palette. Direction is a property of an already-placed connector — not a separate shape — and is set in the connector Properties panel after the connector is drawn.
Toolbox Connector Shapes
| Shape | Icon | Mermaid Output | Available In |
|---|---|---|---|
| Synchronous | Rel(...) |
L0, L1, L2, L3, Deployment | |
| Asynchronous | (dashed badge) | Rel(...) + UpdateRelStyle($lineStyle=dashed) |
L0, L1, L2, L3, Deployment |
| Bidirectional | BiRel(...) |
L0, L1, L2, L3 | |
| Numbered Step | Rel(...) with step prefix |
Dynamic only | |
| Numbered Step (Async) | (dashed badge) | Rel(...) + dashed style with step prefix |
Dynamic only |
| Return / Callback | Rel_Back(...) |
Dynamic only |
Note
Bidirectional vs Rel_Back: These are different tools.
BiReladds arrowheads to both ends of a single connector — use it when the relationship is genuinely two-way.Rel_Backis a directional variant that reverses the rendered arrow but keeps source and target in their logical markup order — use it for response or acknowledgement arrows in Dynamic step sequences.
Connector Direction
| Direction | Mermaid Macro | When to use |
|---|---|---|
| Auto (default) | Rel |
Layout engine decides; start here for any new connector |
| Down | Rel_D |
Top-to-bottom hierarchical flow; parent → child calls |
| Up | Rel_U |
Bottom-to-top callbacks or events bubbling up |
| Left | Rel_L |
Return path in a left-to-right layout |
| Right | Rel_R |
Sequential pipeline steps in a left-to-right layout |
| Back | Rel_Back |
Response or ack — arrow direction reversed visually; FROM/TO entities in markup stay in their original order |
| Neighbor | Rel_Neighbor |
Layout hint: place target node adjacent to source; minimises edge length for tightly coupled pairs |
What Can Connect With What
The current code filters which connector tools are visible by diagram type, but it does not enforce a separate semantic source-target matrix. That means the UI decides which connector templates are available, but it does not currently encode a hard rule such as “Person can only connect to System” or “Container cannot connect to Container Instance.”
Because of that, this section is intentionally advisory. It groups sensible connections by diagram scope without pretending the product has an enforced compatibility validator.
Advisory Connection Map
| Diagram | Typical source categories | Typical target categories | Connector tools |
|---|---|---|---|
| L0 / L1 | Person, System | System, external System | Synchronous, Asynchronous, Bidirectional |
| L2 | Person, System, Container, Container Instance | System, Container, Container Instance, external System, external Container | Synchronous, Asynchronous, Bidirectional |
| L3 | Person, external Person, external System, Component | Component, external Component, System (advanced), external System | Synchronous, Asynchronous, Bidirectional |
| Dynamic | Person, System, Container, external variants | Same participants in sequence order | Numbered Step, Numbered Step (Async), Return / Callback |
| Deployment | Infrastructure Node, Container Instance | Infrastructure Node, Container Instance, external Container Instance | Synchronous, Asynchronous |
Suggested Next Step
If we want the toolbox to become easier to reason about at scale, the next useful enhancement would be a compatibility hint matrix that reacts to the currently selected source shape and diagram type. That should probably be introduced gradually:
- Keep the current diagram-type filtering.
- Add source-shape compatibility hints in the inspector or toolbox hover text.
- Hide only genuinely impossible combinations.
- Leave rare advanced combinations visible behind an explicit advanced toggle so the toolbox stays understandable.
How Imported Notation Maps to Shapes
The Mermaid macro listed in each table above is the exact notation that the import wizard reads. When you paste markup from an external tool — such as Structurizr, draw.io, a hand-crafted DSL file, or a captured export from another C4 tool — Nodinite processes it as follows:
Parse — Each C4 macro (
ContainerDb_Ext,Component_Ext,Rel_Back, etc.) is identified and matched against the shape vocabulary on this page. The diagram type declaration on the first line (C4Context,C4Container,C4Component,C4Deployment,C4Dynamic) tells the parser which shape tier to expect.Match — Each parsed node name is looked up in your Repository by display name:
Container(...)→ Services (prefer typed match byC4ContainerTypeif available)System(...)/Person(...)→ SystemsComponent(...)→ IntegrationsBoundary(...)/Container_Boundary(...)/Deployment_Node(...)→ boundaries or deployment metadata, depending on the diagram type
Review and Resolve — Match results are shown as Matched, NameConflict, or NotFound before anything is saved. You can reassign or skip any node in this step.
Apply — The diagram is created with all nodes, boundaries, connectors, and automatic cross-diagram drill-through links.
Macros not in this reference (for example, newer Mermaid C4 additions or PlantUML-only syntax variants) are skipped, and the count of skipped directives is shown as an informational note in the import result header.
Toolbox Section Order by Diagram Type
| Diagram | Toolbox Sections (in order) |
|---|---|
| L0 System Landscape | Persons · Systems · Connectors |
| L1 System Context | Persons · Systems · Connectors |
| L2 Container | Persons · Containers · Databases · Queues & Streams · External Systems · External Containers · Boundaries · Connectors |
| L3 Component | Components · External Actors · Boundaries · Connectors · Advanced ▶ (L1 System shapes, collapsed) |
| Dynamic | Participants · Connectors |
| Deployment | Infrastructure Nodes · Container Instances · Connectors |