D2 Diagram Creation Skill
Overview
Generate clear, well-structured, and visually appealing D2 diagrams from textual descriptions. D2 is a modern diagram scripting language that transforms text into professional diagrams with support for icons, styling, containers, and multiple layout options.
When to Use This Skill
Use this skill when:
- Creating system architecture diagrams
- Visualizing data flows or processes
- Drawing network topologies
- Illustrating software component relationships
- Creating flowcharts or decision trees
- Designing database schemas
- Showing microservices architectures
- Any request involving "create a diagram," "visualize," "draw," or "show relationships"
Prerequisites
CRITICAL: Before creating any diagram, read the reference files to understand D2 syntax and available icons:
- Read
references/d2_syntax_reference.mdfor syntax patterns and examples - Read
references/d2_validated_icons_list.mdfor available icon URLs
Diagram Creation Workflow
Step 1: Analyze the Requirements
Carefully review the provided description to identify:
- Core Components: What are the main elements/entities?
- Relationships: How do components connect or interact?
- Hierarchy: Are there groupings or containers?
- Flow Direction: What's the logical flow (left-to-right, top-to-bottom)?
- Special Requirements: Styling, colors, icons, or specific visual needs?
Example Analysis:
Request: "Create a diagram showing a web application with users connecting to a load balancer, which distributes traffic to multiple app servers. The app servers connect to a database."
Analysis:
- Core: Users, Load Balancer, App Servers, Database
- Relationships: Users → Load Balancer → App Servers → Database
- Hierarchy: Could group app servers together
- Direction: Left-to-right flow
- Shapes: person for users, hexagon for load balancer, rectangles for servers, cylinder for database
Step 2: Design the Structure
Create a mental model of the diagram structure:
- Identify Central Element: Place the most important component centrally
- Plan Containers: Group related elements together
- Arrange Flow: Position elements to show natural progression
- Consider Symmetry: Balance the layout for visual appeal
Step 3: Select Shapes and Icons
Choose appropriate shapes and icons for each element:
Shape Selection Guidelines:
person- Users, people, actorscylinder- Databases, data storagehexagon- Gateways, processors, servicescloud- Cloud services, external systemsrectangle- Default for most components, servers, applicationsdiamond- Decision points, conditionalscircle- Start/end points, eventsqueue- Message queues, buffersstored_data- Data stores, caches
Icon Selection:
- Consult
references/d2_validated_icons_list.mdfor available icons - Match icons to component type (e.g., AWS Lambda for serverless functions)
- Use
shape: imageto display icon without border - If no suitable icon exists, use appropriate shape with clear labeling
Step 4: Apply Styling
Create consistent visual appearance:
- Define Classes: Create reusable styles for similar components
- Use Color Coding: Apply colors to distinguish different types or states
- Add Visual Hierarchy: Use size, color, and positioning to show importance
- Maintain Consistency: Apply uniform styling to similar elements
Styling Best Practices:
classes: {
primary_service: {
style.fill: "#4A90E2"
style.stroke: "#2E5C8A"
style.stroke-width: 2
}
database_style: {
shape: cylinder
style.fill: "#48C774"
style.multiple: true
}
}
Step 5: Construct the Diagram
Build the diagram following D2 syntax:
- Start with Direction: Set overall flow direction
- Define Core Elements: Create main shapes with labels
- Add Containers: Group related components
- Create Connections: Link elements with appropriate arrows
- Apply Styling: Add colors, icons, and visual properties
- Add Notes: Include explanatory text where helpful
Step 6: Review and Refine
Before finalizing:
Quality Checklist:
- [ ] All components clearly labeled
- [ ] Connections properly directed and labeled
- [ ] Appropriate shapes/icons used
- [ ] Consistent styling applied
- [ ] Logical flow is evident
- [ ] No overlapping or cluttered elements
- [ ] Container groupings make sense
- [ ] Icons are from validated list
- [ ] Overall layout is balanced
Creating Specific Diagram Types
System Architecture
direction: right
classes: {
service: {
style.fill: "#4A90E2"
style.stroke: "#2E5C8A"
}
db: {
shape: cylinder
style.fill: "#48C774"
}
}
users: Users {
shape: person
icon: https://icons.terrastruct.com/essentials/365-user.svg
}
frontend: Frontend {
class: service
icon: https://icons.terrastruct.com/tech/react.svg
}
backend: Backend Services {
api: API Gateway {
class: service
icon: https://icons.terrastruct.com/aws/Networking%20&%20Content%20Delivery/Amazon-API-Gateway.svg
}
auth: Auth Service {
class: service
}
data: Data Service {
class: service
}
}
database: PostgreSQL {
class: db
icon: https://icons.terrastruct.com/tech/postgresql.svg
}
users -> frontend: Access
frontend -> backend.api: REST API
backend.api -> backend.auth: Authenticate
backend.api -> backend.data: Fetch Data
backend.data -> database: Query
Data Flow Diagram
direction: right
source: Data Source {
shape: cylinder
style.fill: "#E8F5E9"
style.multiple: true
}
ingestion: Data Ingestion {
shape: hexagon
style.fill: "#FFF9C4"
}
processing: Data Processing {
transform: Transform
validate: Validate
enrich: Enrich
style.fill: "#E3F2FD"
}
storage: Data Warehouse {
shape: stored_data
style.fill: "#F3E5F5"
}
analytics: Analytics Layer {
shape: rectangle
style.fill: "#FCE4EC"
}
viz: Visualization {
shape: page
icon: https://icons.terrastruct.com/essentials/dashboard.svg
}
source -> ingestion: Extract {
style.stroke: "#4CAF50"
style.stroke-width: 2
}
ingestion -> processing.transform: Raw Data {
style.animated: true
}
processing.transform -> processing.validate
processing.validate -> processing.enrich
processing.enrich -> storage: Store {
style.stroke: "#2196F3"
style.stroke-width: 2
}
storage -> analytics: Query
analytics -> viz: Display
Network Topology
direction: down
internet: Internet {
shape: cloud
icon: https://icons.terrastruct.com/essentials/214-worldwide.svg
}
firewall: Firewall {
shape: hexagon
style.fill: "#FF5252"
icon: https://icons.terrastruct.com/infra/firewall.svg
}
dmz: DMZ {
direction: right
lb: Load Balancer {
shape: hexagon
icon: https://icons.terrastruct.com/infra/load-balancer.svg
}
web1: Web Server 1 {
shape: rectangle
}
web2: Web Server 2 {
shape: rectangle
}
style.fill: "#FFF3E0"
}
internal: Internal Network {
direction: right
app1: App Server 1
app2: App Server 2
db: Database Cluster {
shape: cylinder
style.multiple: true
icon: https://icons.terrastruct.com/tech/postgresql.svg
}
style.fill: "#E8F5E9"
}
internet -> firewall
firewall -> dmz.lb
dmz.lb -> dmz.web1
dmz.lb -> dmz.web2
dmz.web1 -> internal.app1
dmz.web2 -> internal.app2
internal.app1 -> internal.db
internal.app2 -> internal.db
Microservices Architecture
direction: right
classes: {
service: {
shape: rectangle
style.fill: "#E3F2FD"
style.stroke: "#1976D2"
}
database: {
shape: cylinder
style.fill: "#C8E6C9"
}
queue: {
shape: queue
style.fill: "#FFF9C4"
}
}
users: Users {
shape: person
}
gateway: API Gateway {
shape: hexagon
style.fill: "#B39DDB"
}
services: Microservices {
user_service: User Service {
class: service
}
order_service: Order Service {
class: service
}
payment_service: Payment Service {
class: service
}
notification_service: Notification Service {
class: service
}
}
queues: Message Queues {
order_queue: Order Queue {
class: queue
}
notification_queue: Notification Queue {
class: queue
}
}
databases: Databases {
user_db: User DB {
class: database
}
order_db: Order DB {
class: database
}
payment_db: Payment DB {
class: database
}
}
users -> gateway
gateway -> services.user_service
gateway -> services.order_service
gateway -> services.payment_service
services.user_service -> databases.user_db
services.order_service -> databases.order_db
services.payment_service -> databases.payment_db
services.order_service -> queues.order_queue: Publish
services.payment_service -> queues.order_queue: Subscribe
services.notification_service -> queues.notification_queue: Subscribe
Best Practices
Clarity and Simplicity
- Start Simple: Begin with core elements, add complexity gradually
- Use Descriptive Labels: Choose clear, informative names for all components
- Limit Complexity: If diagram becomes cluttered, split into multiple diagrams or use layers
- Show Key Relationships: Focus on important connections, omit trivial ones
Visual Design
- Consistent Styling: Apply uniform styles to similar component types using classes
- Color Coding: Use colors purposefully to distinguish types or states
- Appropriate Shapes: Match shapes to what they represent
- Balance Layout: Distribute elements evenly, avoid crowding
- Direction Matters: Choose flow direction that matches natural reading or process flow
Icons and Shapes
- Verify Icon URLs: Only use icons from
references/d2_validated_icons_list.md - Use Icons Sparingly: Too many icons can clutter; use for key components
- Consistent Icon Style: Stick to one icon set (e.g., all AWS, all tech icons)
- Fallback to Shapes: If no suitable icon, use appropriate shape with label
Containers and Grouping
- Logical Grouping: Group related components together
- Nested Containers: Use for hierarchical structures
- Clear Boundaries: Make container purposes obvious through naming
- Avoid Over-Nesting: Too many levels makes diagrams hard to read
Connections
- Label Important Connections: Add labels to clarify relationships
- Use Appropriate Arrows: Choose arrow types that match relationship
- Connection Styling: Style connections to show different types or states
- Avoid Crossing Lines: Minimize connection crossings for clarity
Common Pitfalls to Avoid
❌ Don't Use Fake Icon URLs
Wrong:
server: {
icon: https://example.com/fake-icon.svg # This will fail
}
Right:
server: {
icon: https://icons.terrastruct.com/tech/docker.svg # Verified URL
shape: image
}
Or use a shape without an icon:
server: {
shape: rectangle
}
❌ Don't Over-Complicate
Wrong:
# Too many nested levels
system.layer1.layer2.layer3.layer4.component
Right:
# Clear, manageable hierarchy
system: {
frontend
backend
database
}
❌ Don't Forget Direction
Wrong:
# No direction specified, layout may be suboptimal
A -> B -> C -> D
Right:
direction: right # Clear flow direction
A -> B -> C -> D
❌ Don't Mix Styling Approaches
Wrong:
# Inconsistent styling
element1: {
style.fill: "#FF0000"
}
element2: {
style.fill: "#00FF00"
}
element3: {
style.fill: "#0000FF"
}
Right:
# Consistent styling with classes
classes: {
primary: {
style.fill: "#4A90E2"
}
}
element1: { class: primary }
element2: { class: primary }
element3: { class: primary }
Advanced Techniques
Layout Optimization
vars: {
d2-config: {
layout-engine: elk # Try 'elk' for better hierarchical layouts
pad: 50 # Adjust padding
}
}
# Use direction to control flow
direction: right
# Use grid for structured layouts
grid_container: {
grid-rows: 2
grid-columns: 3
item1; item2; item3
item4; item5; item6
}
Reusable Styles with Classes
classes: {
critical: {
style.fill: "#FF5252"
style.stroke: "#D32F2F"
style.stroke-width: 3
}
normal: {
style.fill: "#4CAF50"
style.stroke: "#388E3C"
}
inactive: {
style.fill: "#BDBDBD"
style.opacity: 0.5
}
}
# Apply classes
prod_server: { class: critical }
dev_server: { class: normal }
old_server: { class: inactive }
Interactive Elements
component: {
link: https://docs.example.com/component
tooltip: Click to view documentation
}
Notes and Annotations
# Simple note attached to an element
important_element: Critical Component
important_element.note: |md
This component handles:
- User authentication
- Session management
- Rate limiting
|
# Standalone floating note (root-level only)
# 'near' with constants only works on ROOT-LEVEL shapes
# Valid positions: top-left, top-center, top-right, center-left, center-right, bottom-left, bottom-center, bottom-right
diagram_note: Architecture Overview {
shape: text
near: top-center
style.font-size: 14
}
Output Format
Always provide:
- Complete D2 Code: Ready to use, properly formatted
- Clear Comments: Explain key sections
- Proper Syntax: Follow D2 language specifications
- Working Icons: Only use validated icon URLs
The output should be a complete .d2 file that can be:
- Rendered using D2 CLI:
d2 diagram.d2 output.svg - Used in D2 playground: https://play.d2lang.com
- Integrated into documentation systems
Resources
Reference Files
references/d2_syntax_reference.md: Comprehensive D2 syntax guide with examplesreferences/d2_validated_icons_list.md: Verified icon URLs organized by category
Quick Reference
Basic Shape:
element: Label
Shape with Type:
element: Label {
shape: cylinder
}
Connection:
A -> B: Connection Label
Container:
container: Container Name {
child1
child2
child1 -> child2
}
Styling:
element: {
style.fill: "#4A90E2"
style.stroke: "#2E5C8A"
}
Icon:
element: {
icon: https://icons.terrastruct.com/tech/docker.svg
shape: image
}
Tips for Success
- Read References First: Always consult syntax and icon references before starting
- Plan Before Coding: Sketch out structure mentally or on paper
- Iterate: Start simple, refine iteratively
- Test Layouts: Try different directions and layout engines
- Use Examples: Adapt provided examples to your needs
- Stay Organized: Use containers to maintain structure
- Be Consistent: Apply uniform styling throughout
- Document Choices: Add comments explaining non-obvious decisions
Troubleshooting
Diagram looks cluttered?
- Simplify: Remove non-essential elements
- Use containers to group related items
- Try different layout engine (elk vs dagre)
- Split into multiple diagrams or layers
Icons not appearing?
- Verify icon URL is from validated list
- Check URL is accessible (HTTPS required)
- Use
shape: imageto remove border - Fallback to shapes if icon unavailable
Layout not as expected?
- Try different
directionsetting - Experiment with layout engine (
elkvsdagre) - Adjust container groupings
- Use grid layouts for structured arrangements
Connections crossing awkwardly?
- Reorder element definitions
- Adjust container organization
- Try different flow direction
- Simplify connection paths
Remember: The goal is to create clear, informative diagrams that effectively communicate system structure and relationships. When in doubt, prioritize clarity over complexity.