How to Visualize Your Project Architecture with C4PlantUML
This guide explains why architecture diagrams matter, introduces the C4 modeling method, shows how to use C4PlantUML with PlantUML to create context, container, component, and code‑level diagrams, and provides step‑by‑step instructions and example code for practical implementation.
Background
Architecture diagrams help development teams—including engineers, testers, architects, product managers, and designers—visualize and communicate the software structure, ensuring a shared understanding and unified perception of the system.
Implementation Path
The chosen solution is C4PlantUML , which combines the C4 modeling methodology with PlantUML’s text‑based diagram engine.
C4 Model Overview
The C4 model abstracts a system into four hierarchical levels:
Context : high‑level system landscape.
Container : major runtime containers such as applications, databases, and services.
Component : logical building blocks inside containers.
Code : detailed class or source‑code view.
Three supplemental views—system landscape, dynamic (sequence) diagram, and deployment diagram—complete the description.
Layout Options
LAYOUT_TOP_DOWN: top‑to‑bottom flow. LAYOUT_RIGHT_LEFT: left‑to‑right flow. LAYOUT_WITH_LEGEND: includes a legend. LAYOUT_AS_SKETCH: sketch‑style layout.
Context Elements
Person: internal actor. Person_Ext: external actor. System: software system. System_Ext: external software system. SystemDb: system database. SystemDb_Ext: external database. System_Boundry: system boundary. Enterprise_Boundry: enterprise boundary.
Container Elements
Container: runtime container. ContainerDb: container‑level database. Container_Boundry: container boundary.
Component Elements
Component: logical component. ComponentDb: component‑level database.
Code‑Level Relationships
Boundry: visual boundary. Rel: top‑down relationship. Rel_Back: reverse relationship. Rel_U: upward relationship. Rel_D: downward relationship. Rel_L: left‑to‑right relationship. Rel_R: right‑to‑left relationship.
Example Diagrams
Context diagram example (illustrates an e‑commerce system and its external actors):
@startuml
"enterprise"
!include ../C4_Context.puml LAYOUT_TOP_DOWN LAYOUT_WITH_LEGEND()
Person(customer, "Customer", "A customer of the tool")
Enterprise_Boundary(c0, "Tool") {
Person(csa, "Customer Service Agent", "Handles inquiries")
System(ecommerce, "E‑commerce System", "Allows online purchase of tools")
System(fulfilment, "Fulfilment System", "Processes and delivers orders")
}
System(taxamo, "Taxamo", "Calculates local tax and fronts Braintree payments")
System(braintree, "Braintree", "Handles credit‑card payments")
System(post, "Post Service", "Calculates worldwide shipping costs")
Rel_R(customer, csa, "Consults", "Phone")
Rel_R(customer, ecommerce, "Places order")
Rel(customer, ecommerce, "Queries order info")
Rel_R(ecommerce, fulfilment, "Sends order info")
Rel_D(fulfilment, post, "Gets shipping cost")
Rel_D(ecommerce, taxamo, "Proxies credit‑card handling")
Rel_L(taxamo, braintree, "Uses credit card")
Lay_D(customer, braintree)
@endumlContainer diagram example (online banking system):
@startuml
!include ../C4_Container.puml LAYOUT_TOP_DOWN LAYOUT_WITH_LEGEND()
title "Online Banking System Container Diagram"
Person(customer, "Customer", "Has a private bank account")
System_Boundary(c1, "Online Banking") {
Container(web_app, "Web Application", "Java, Spring MVC", "Delivers static content and SPA")
Container(spa, "Single‑Page Application", "JavaScript, Angular", "Provides full banking features in browser")
Container(mobile_app, "Mobile Application", "C#, Xamarin", "Limited banking features on mobile devices")
ContainerDb(database, "Database", "SQL", "Stores registration info, auth tokens, logs")
Container(backend_api, "API Application", "Java, Docker", "Exposes banking functions via API")
}
System_Ext(email_system, "Email System", "Network mail exchange")
System_Ext(banking_system, "Mainframe Banking System", "Stores core customer, account, transaction data")
Rel(customer, web_app, "Uses", "HTTPS")
Rel(customer, spa, "Uses", "HTTPS")
Rel(customer, mobile_app, "Uses")
Rel_Neighbor(web_app, spa, "Transfers")
Rel(spa, backend_api, "Uses", "Async, JSON/HTTPS")
Rel(mobile_app, backend_api, "Uses", "Async, JSON/HTTPS")
Rel_Back_Neighbor(database, backend_api, "Read/Write", "Sync, JDBC")
Rel_Back(customer, email_system, "Sends email to")
Rel_Back(email_system, backend_api, "Sends email", "SMTP")
Rel_Neighbor(backend_api, banking_system, "Uses", "Sync/Async, XML/HTTPS")
@endumlComponent diagram example (API layer of the same system):
@startuml
!include ../C4_Component.puml LAYOUT_WITH_LEGEND()
title "Online Banking API Component Diagram"
Container(spa, "SPA", "JavaScript, Angular", "Provides full banking UI")
Container(ma, "Mobile App", "Xamarin", "Limited UI on mobile")
ContainerDb(db, "Database", "Relational Schema", "Stores user data, tokens, logs")
System_Ext(mbs, "Mainframe Banking System", "Core account and transaction data")
Container_Boundary(api, "API Application") {
Component(sign, "Login Controller", "MVC Rest", "Handles user login")
Component(accounts, "Account Summary Controller", "MVC Rest", "Provides account overview")
Component(security, "Security Component", "Spring Bean", "Login, password change")
Component(mbsfacade, "Mainframe Facade", "Spring Bean", "Facade to mainframe system")
}
Rel(sign, security, "Uses")
Rel(accounts, mbsfacade, "Uses")
Rel(security, db, "Read/Write", "JDBC")
Rel(mbsfacade, mbs, "Uses", "XML/HTTPS")
Rel(spa, sign, "Uses", "JSON/HTTPS")
Rel(spa, accounts, "Uses", "JSON/HTTPS")
Rel(ma, sign, "Uses", "JSON/HTTPS")
Rel(ma, accounts, "Uses", "JSON/HTTPS")
@endumlSequence Diagram Example
@startuml
actor user as User
participant browser as Browser
participant front as Frontend
participant loginServer as LoginServer
participant db as Database
User -> Browser : Open login page
Browser -> Frontend : Load resources, enter credentials
Frontend -> LoginServer : AJAX request
LoginServer -> Database : Verify credentials
Database --> LoginServer : Return result
LoginServer --> Browser : Return response
@endumlC4PlantUML Overview
C4PlantUML merges the C4 modeling approach with PlantUML, offering a concise textual way to describe and share software architecture. PlantUML is a widely adopted text‑based diagram tool that can generate many UML diagram types.
Tooling Integration
VS Code: install PlantUML and PlantUML Preview extensions, plus JDK and Graphviz.
IntelliJ IDEA: install PlantUML plugin and Graphviz.
Open any .puml file to start drawing.
Naming Conventions
Context diagram: xxx_context.puml Container diagram: xxx_container.puml Component diagram: xxx_component.puml Sequence diagram: xxx_sequence.puml Use‑case diagram: xxx_usecase.puml Class diagram: xxx_class.puml Activity diagram: xxx_activity.puml State diagram: xxx_state.puml Object diagram: xxx_object.puml Deployment diagram: xxx_deployment.puml Timing diagram:
xxx_timing.pumlDrawing Steps
Create a model file named xxx_project.puml following the naming rules.
Include the appropriate C4 template, e.g., !include path/C4_Component.puml.
Use the provided functions (e.g., LAYOUT_TOP_DOWN, LAYOUT_WITH_LEGEND) to compose the diagram.
Conclusion
If you remember only one thing, it is that C4PlantUML gives you a straightforward, text‑based method to describe and visualise software architecture across multiple abstraction levels.
IT Architects Alliance
Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
