Creates and manages C4 architecture diagrams using PlantUML...
This skill helps you create and manage C4 architecture diagrams using the PlantUML format. C4 diagrams provide a hierarchical way to visualize software architecture at different levels of detail, from high-level system context down to low-level components.
The C4 model uses four diagram types:
All diagrams are stored as .puml files in doc/diagrams/ and rendered to PNG images using the public PlantUML server.
Before using this skill, ensure you have:
Note: This skill uses only standard library dependencies. No package managers or external installations required beyond Python itself.
Creating C4 diagrams follows a five-phase workflow:
doc/diagrams/ with subdirectories for each diagram typeEach phase includes validation steps to ensure correctness before proceeding to the next phase.
Before creating diagrams, verify that the directory structure exists:
Use the Bash tool to check:
ls -la doc/diagrams 2>/dev/null
If the output shows subdirectories context/, container/, component/, and sequence/, proceed to Phase 2.
If the structure doesn't exist, run the initialization script:
bash .claude/skills/c4-diagrams/scripts/init-structure.sh
Expected behavior:
doc/diagrams/ at project root if missingdoc/diagrams/context/ - For context-level diagramsdoc/diagrams/container/ - For container-level diagramsdoc/diagrams/component/ - For component-level diagramsdoc/diagrams/sequence/ - For sequence diagramsAfter running the script, confirm the structure was created:
ls -R doc/diagrams
You should see all four subdirectories.
Error handling:
Choose the appropriate diagram type based on what you want to visualize:
Context Diagrams (context/)
Container Diagrams (container/)
Component Diagrams (component/)
Sequence Diagrams (sequence/)
For detailed guidance on when to use each type, see Diagram Types Guide.
Before creating a new diagram, check if it already exists:
Determine the diagram name (convert to lowercase, replace spaces with hyphens):
system-contextweb-applicationCheck for existing file:
ls doc/diagrams/{type}/{name}.puml 2>/dev/null
If the file exists:
If the file doesn't exist:
To create a new diagram, read the appropriate template and write it to the target location:
Read the template:
Read .claude/skills/c4-diagrams/templates/{type}.puml
Where {type} is one of: context, container, component, sequence
Optionally customize the template:
Write to target location:
Write doc/diagrams/{type}/{name}.puml
Validation:
ls doc/diagrams/{type}/{name}.pumlBefore adding elements, read the diagram file to understand what's already there:
Read doc/diagrams/{type}/{name}.puml
Identify:
Based on the user's request, identify what elements need to be added:
Common element types by diagram:
Context diagrams:
Person(id, "Name", "Description") - Users and actorsSystem(id, "Name", "Description") - Your systemSystem_Ext(id, "Name", "Description") - External systemsContainer diagrams:
Container(id, "Name", "Technology", "Description") - Apps, services, databasesContainerDb(id, "Name", "Technology", "Description") - Databases specificallyContainerQueue(id, "Name", "Technology", "Description") - Message queuesComponent diagrams:
Component(id, "Name", "Technology", "Description") - Components within a containerComponentDb(id, "Name", "Technology", "Description") - Database componentsComponentQueue(id, "Name", "Technology", "Description") - Queue componentsSequence diagrams:
Container(cache, "Cache", "Redis", "Desc") not Container_Ext(...)Boundaries (Context/Container/Component diagrams only - NOT sequence):
System_Boundary(id, "Name", "Optional Description") {
// Elements inside the boundary (indented with 2 spaces)
}
For complete syntax reference, see Syntax Reference.
To add elements, use the Edit tool to insert element definitions at the appropriate location:
Important syntax rules:
Example additions:
For a context diagram:
Person(user, "User", "A customer using the system")
System(main_system, "Main System", "The core application")
System_Ext(payment_gateway, "Payment Gateway", "External payment processor")
For a container diagram:
Container(web_app, "Web Application", "React", "Provides UI for users")
ContainerDb(database, "Database", "PostgreSQL", "Stores application data")
Container(api, "API Server", "Node.js/Express", "Handles business logic")
After adding elements, verify correctness:
Before adding relationships, read the diagram to identify:
Based on the user's request and diagram logic, identify which elements should be connected:
Relationship syntax:
Rel(source_id, target_id, "Description")
Rel(source_id, target_id, "Description", "Technology/Protocol")
Directional variants (optional, for layout control):
Rel_U - Relationship pointing upRel_D - Relationship pointing downRel_L - Relationship pointing leftRel_R - Relationship pointing rightExamples:
Rel(user, web_app, "Uses", "HTTPS")
Rel(web_app, api, "Makes API calls", "REST/JSON")
Rel(api, database, "Reads/writes", "JDBC")
Rel(main_system, payment_gateway, "Processes payments", "API")
To add relationships, use the Edit tool to insert them after the element definitions:
Best practices:
For sequence diagrams:
== Step Name ==group blocks for sub-processes:== Authentication ==
group Login Process
Rel(user, api, "Submits credentials")
Rel(api, database, "Verifies user")
end
After adding relationships, verify correctness:
If validation fails:
To render the diagram, run the rendering script:
python3 .claude/skills/c4-diagrams/scripts/render-diagram.py doc/diagrams/{type}/{name}.puml
Example:
python3 .claude/skills/c4-diagrams/scripts/render-diagram.py doc/diagrams/context/system-context.puml
Expected behavior:
doc/diagrams/context/system-context.pngAfter rendering, confirm the PNG was created:
ls -lh doc/diagrams/{type}/{name}.png
The script includes:
If rendering fails, the script will provide specific error messages:
Network errors:
HTTP 400 errors:
HTTP 429 errors:
HTTP 5xx errors:
After successful rendering:
Option 1: Iterate on the diagram
Option 2: Create additional diagrams
Option 3: Explore advanced features
ā Don't use hyphens in element IDs ā ā Do use underscores:
System(web-app, "Web App", "Desc") // WRONG
System(web_app, "Web App", "Desc") // CORRECT
ā Don't omit technology for containers/components ā ā Do always include it:
Container(api, "API Server", "Handles logic") // WRONG
Container(api, "API Server", "Node.js", "Handles logic") // CORRECT
ā Don't forget closing braces ā ā Do always close boundaries:
System_Boundary(backend, "Backend") {
Container(api, "API", "Node.js", "Server")
// WRONG - missing }
} // CORRECT
ā Don't reference undefined IDs ā ā Do ensure all IDs are defined:
Rel(user, app, "Uses") // WRONG if 'user' not defined first
ā Don't use boundaries in sequence diagrams ā ā Do use flat participant lists:
' WRONG - sequence diagrams don't support boundaries
Container_Boundary(backend, "Backend") {
Container(api, "API", "Node.js", "Server")
}
' CORRECT - flat list of participants
Container(api, "API", "Node.js", "Server")
ā Don't use _Ext suffixes in sequence diagrams ā ā Do use regular variants:
Container_Ext(cache, "Cache", "Redis", "Cache") // WRONG in sequence
Container(cache, "Cache", "Redis", "Cache") // CORRECT
ā ļø Important: Place diagrams in correct subdirectories (doc/diagrams/context/, container/, component/, sequence/)
ā ļø Important: Validate PUML syntax before rendering to avoid errors and server requests
ā ļø Important: Sequence diagrams have unique syntax constraints - see template and syntax reference
Load these on-demand for deeper information: