| name | structurizr-architecture-as-code |
|---|---|
| description | Generate Structurizr DSL (.dsl) from source code context. Comprehensive reference for Structurizr DSL syntax — workspace, model, views, styles, deployment, configuration, CLI. Use when asked to diagram, visualize, or document software architecture from code using C4 model. |
Structurizr is the reference implementation of the C4 model, created by the C4 model's author (Simon Brown). You describe systems in .dsl files using the Structurizr DSL, and the tooling generates multiple diagram types from a single model.
Repository: https://github.com/structurizr/structurizr
Docs: https://docs.structurizr.com
Playground: https://playground.structurizr.com
Extension files: .dsl
A Structurizr workspace is defined in a single .dsl file (conventionally workspace.dsl), optionally split via !include.
project/
├── workspace.dsl ← main entry point
├── model/
│ ├── people.dsl ← person definitions
│ ├── systems.dsl ← software systems
│ └── deployment.dsl ← deployment environment
├── views.dsl ← all view definitions
├── styles.dsl ← element/relationship styles
└── docs/ ← !docs and !adrs content
Use !include to split large workspaces:
workspace {
model {
!include model/
}
views {
!include views.dsl
}
}workspace [name] [description] {
!identifiers hierarchical // dot-separated IDs (recommended)
!impliedRelationships true // auto-create implicit rels via parent
model { ... }
views { ... }
configuration { ... }
}Key directives:
!identifiers hierarchical— enables dot-path identifiers (System.Container.Component); flat (default) uses plain names!impliedRelationships true— if A→B exists and A has child A.C, then A.C→B is auto-created!include <file|directory|url>— import DSL fragments!docs <path>— attach Markdown/AsciiDoc documentation!adrs <path>— attach Architecture Decision Records!script <groovy|kotlin|ruby|javascript>— run scripts during parseworkspace extends <file|url> { ... }— extend another workspace
Defines the architecture: people, software systems, containers, components, and relationships.
model {
// People
user = person "User" "A customer of the system" "External"
admin = person "Admin" "System administrator"
// Enterprise boundary (visual grouping)
enterprise "My Company" {
// Software systems
system = softwareSystem "E-Commerce Platform" "Allows customers to browse and purchase" {
// Containers
webapp = container "Web Application" "Serves the frontend" "React/TypeScript" {
// Components
appComponent = component "App Component" "Root React component" "React"
router = component "Router" "Client-side routing" "React Router"
apiClient = component "API Client" "HTTP client for backend" "Axios"
}
api = container "API Gateway" "Handles all API requests" "Node.js/Express" {
authController = component "Auth Controller" "Authentication endpoints" "Express"
orderController = component "Order Controller" "Order management" "Express"
serviceLayer = component "Service Layer" "Business logic" "TypeScript"
repoLayer = component "Repository Layer" "Data access" "TypeScript"
}
db = container "Database" "Stores all persistent data" "PostgreSQL"
cache = container "Cache" "Session and query cache" "Redis"
queue = container "Message Queue" "Async event processing" "RabbitMQ"
}
// Another system
crm = softwareSystem "CRM System" "Customer relationship management" "Internal"
}
// External systems
paymentGateway = softwareSystem "Stripe" "Payment processing" "External"
emailService = softwareSystem "SendGrid" "Email delivery" "External"
// Relationships
user -> system.webapp "Browses products, places orders" "HTTPS"
system.webapp -> system.api "Makes API calls" "REST/JSON over HTTPS"
system.api -> system.db "Reads/writes data" "JDBC/SQL"
system.api -> system.cache "Caches queries" "Redis Protocol"
system.api -> system.queue "Publishes events" "AMQP"
system.api -> paymentGateway "Processes payments" "HTTPS/API"
system.queue -> emailService "Sends notifications" "HTTPS/API"
admin -> system.api "Manages system" "HTTPS"
// Component-level relationships (inside container)
system.webapp.router -> system.webapp.appComponent "Renders"
system.webapp.appComponent -> system.webapp.apiClient "Uses"
system.webapp.apiClient -> system.api "Makes requests" "REST/JSON"
system.api.authController -> system.api.serviceLayer "Delegates"
system.api.orderController -> system.api.serviceLayer "Delegates"
system.api.serviceLayer -> system.api.repoLayer "Uses"
system.api.repoLayer -> system.db "Queries" "JDBC"
// Deployment
deploymentEnvironment "Production" {
deploymentNode "AWS" {
deploymentNode "EKS Cluster" "Kubernetes" "EKS" {
deploymentNode "Node Pool" "Worker nodes" "EC2" {
webappInstance = containerInstance system.webapp
apiInstance = containerInstance system.api
}
}
deploymentNode "RDS" {
dbInstance = containerInstance system.db
}
deploymentNode "ElastiCache" {
cacheInstance = containerInstance system.cache
}
deploymentNode "Amazon MQ" {
queueInstance = containerInstance system.queue
}
}
deploymentNode "External Services" {
infrastructureNode "Stripe API" "Payment gateway" "HTTPS"
infrastructureNode "SendGrid API" "Email service" "HTTPS"
}
}
}| Keyword | Usage | Default Tags |
|---|---|---|
person <name> [desc] [tags] |
Users, actors, roles | Element, Person |
softwareSystem <name> [desc] [tags] |
Top-level systems | Element, Software System |
container <name> [desc] [tech] [tags] |
Apps, databases, queues within a system | Element, Container |
component <name> [desc] [tech] [tags] |
Modules within a container | Element, Component |
deploymentNode <name> [desc] [tech] [tags] [instances] |
Infrastructure | Element, Deployment Node |
infrastructureNode <name> [desc] [tech] [tags] |
LBs, firewalls, DNS | Element, Infrastructure Node |
containerInstance <ref> |
Deployed instance of a container | Container Instance |
softwareSystemInstance <ref> |
Deployed instance of a system | Software System Instance |
instanceOf <ref> |
Alias for container/softwareSystemInstance | — |
source -> destination "Description" "Technology" {
tags "Tag1"
url "https://..."
properties { key "value" }
perspectives { ... }
}->defines a unidirectional relationship- Description and technology are both optional strings
- Tags are comma-separated or use
tag "X"inside the block
group "Team Alpha" {
system1 = softwareSystem "System 1"
system2 = softwareSystem "System 2"
}Groups render as visual boundaries. Nesting is supported. Groups only work at the same abstraction level (people+systems, containers, or components).
element "queue" "Message Queue" {
tag "Queue"
icon "https://example.com/queue.png"
}views {
// System Landscape — all people and systems
systemlandscape "landscape" "System Landscape" {
include *
autoLayout lr
}
// System Context — one system and its neighbors
systemContext system "context" "System Context Diagram" {
include *
exclude paymentGateway
autoLayout tb
}
// Container — containers inside a system
container system "containers" "Container Diagram" {
include *
autoLayout lr
}
// Component — components inside a container
component system.api "api-components" "API Components" {
include *
autoLayout tb
}
// Deployment — infrastructure topology
deployment system "Production" "prod-deployment" "Production Deployment" {
include *
autoLayout lr
}
// Dynamic — sequence/flow diagram
dynamic system "checkout" "Checkout Flow" {
user -> system.webapp "Opens checkout"
system.webapp -> system.api "POST /checkout" "REST"
system.api -> paymentGateway "Charge card" "HTTPS"
system.api -> system.db "Save order" "JDBC"
system.api -> system.queue "Publish OrderCreated" "AMQP"
system.webapp <- system.api "Order confirmation" "REST"
autoLayout lr
}
// Filtered — filtered view based on tags
filtered "containers" include "Internal" "internal-containers"
// Image — embed PlantUML/Mermaid/custom image
image system.api "api-plantuml" {
plantuml {
// PlantUML content
}
}
// Styles
styles {
element "Element" {
background #438dd5
color #ffffff
}
element "Person" {
shape Person
background #08427b
}
element "Software System" {
background #1168bd
}
element "Container" {
background #438dd5
}
element "Component" {
background #85bbf0
color #000000
}
element "External System" {
background #999999
}
element "Database" {
shape Cylinder
}
element "Queue" {
shape Pipe
}
relationship "Relationship" {
routing Orthogonal
style solid
}
// Dark mode overrides
dark {
element "Element" {
background #1a1a2e
color #e0e0e0
}
}
}
// Themes
themes default
// themes "https://static.structurizr.com/themes/aws/theme.json"
}| Type | Syntax | Purpose |
|---|---|---|
| System Landscape | systemlandscape [key] [title] |
All people and systems |
| System Context | systemContext <element> [key] [title] |
One system + neighbors |
| Container | container <element> [key] [title] |
Containers in a system |
| Component | component <element> [key] [title] |
Components in a container |
| Deployment | deployment <element> <env> [key] [title] |
Infrastructure topology |
| Dynamic | dynamic <element> [key] [title] |
Sequence/flow diagram |
| Filtered | filtered <key> <include|exclude> <tags> [key] |
Tag-filtered view |
| Image | image <element> [key] |
Embed external diagram |
| Custom | custom ... |
Custom view type |
include * // all elements in scope
include elementIdentifier // specific element
include * -> * // all relationships
include element1 -> element2 // relationship between two
include * -> element // all inbound to element
include element -> * // all outbound from element
exclude elementIdentifier // remove elementautoLayout tb // top-to-bottom (default)
autoLayout bt // bottom-to-top
autoLayout lr // left-to-right
autoLayout rl // right-to-left
autoLayout tb 200 100 // with rankSep and nodeSepanimation {
step 1 {
element1
element2
}
step 2 {
element3
}
}styles {
// Element styles — keyed by tag name
element "Element" {
shape Box // Box|RoundedBox|Circle|Ellipse|Hexagon|Diamond|Cylinder|Person|Robot|Folder|WebBrowser|Window|Terminal|MobileDevicePortrait|Component
background #438dd5
color #ffffff
stroke #2d6ca2
strokeWidth 2
fontSize 24
border solid // solid|dashed|dotted
opacity 80
width 400
height 200
icon <file|url>
metadata true // show metadata
description true // show description
}
// Relationship styles
relationship "Relationship" {
thickness 2
color #438dd5
style solid // solid|dashed|dotted
routing Orthogonal // Direct|Orthogonal|Curved
fontSize 12
width 200
position 50 // label position (0-100)
opacity 100
}
// Dark mode overrides
dark {
element "Element" {
background #1a1a2e
}
}
}Box, RoundedBox, Circle, Ellipse, Hexagon, Diamond, Cylinder, Person, Robot, Folder, WebBrowser, Window, Terminal, MobileDevicePortrait, MobileDeviceLandscape, Component, Pipe (undocumented but works for queues)
themes default
themes "https://static.structurizr.com/themes/aws/theme.json"
themes "https://static.structurizr.com/themes/azure/theme.json"
themes "https://static.structurizr.com/themes/gcp/theme.json"
themes "https://static.structurizr.com/themes/kubernetes/theme.json"Multiple themes can be combined. Later themes override earlier ones.
configuration {
scope softwaresystem // landscape|softwaresystem|none
visibility private // private|public
users {
"user@example.com" read
"admin@example.com" write
}
properties {
structurizr.access.key "..."
structurizr.access.secret "..."
}
}Recommended: Docker (Structurizr Local)
# Pull and run Structurizr Local
docker pull structurizr/structurizr
docker run -it --rm -p 8080:8080 \
-v /path/to/workspace:/usr/local/structurizr \
structurizr/structurizr localThen open http://localhost:8080 to view and edit diagrams.
Alternative: Download binary
- Get from https://github.com/structurizr/structurizr/releases
- Requires Java 17+
- Run via
./structurizr.sh <command>(Linux/Mac) orstructurizr.bat <command>(Windows)
| Command | Purpose |
|---|---|
validate -workspace workspace.dsl |
Validate DSL syntax and model consistency |
inspect -workspace workspace.dsl |
Run architectural inspections (returns violation count) |
inspect -workspace workspace.dsl -severity error,warning |
Inspect, showing only errors+warnings |
export -workspace workspace.dsl -format plantuml -output diagrams/ |
Export to PlantUML |
export -workspace workspace.dsl -format plantuml/c4plantuml -output diagrams/ |
Export to C4-PlantUML |
export -workspace workspace.dsl -format mermaid -output diagrams/ |
Export to Mermaid |
export -workspace workspace.dsl -format static -output site/ |
Export to static HTML site |
export -workspace workspace.dsl -format png -output images/ |
Export to PNG (browser renderer) |
export -workspace workspace.dsl -format svg -output images/ |
Export to SVG (browser renderer) |
export -workspace workspace.dsl -format json |
Export to Structurizr JSON format |
local |
Start local viewer/editor on port 8080 |
list -workspace workspace.dsl |
List elements in workspace |
push -workspace workspace.dsl -key KEY -secret SECRET |
Push to Structurizr cloud |
pull -workspace workspace.dsl -id ID -key KEY -secret SECRET |
Pull from Structurizr cloud |
merge -workspace workspace.dsl -into target.dsl |
Merge layout info into workspace |
version |
Show version |
Docker usage for any command:
docker run -it --rm -v $PWD:/usr/local/structurizr structurizr/structurizr validate -workspace workspace.dsl
docker run -it --rm -v $PWD:/usr/local/structurizr structurizr/structurizr export -workspace workspace.dsl -format mermaid -output diagrams
docker run -it --rm -v $PWD:/usr/local/structurizr structurizr/structurizr inspect -workspace workspace.dsl -severity error,warningAfter generating a .dsl file, always verify:
-
Validate syntax:
docker run -it --rm -v $PWD:/usr/local/structurizr structurizr/structurizr validate -workspace workspace.dslZero output = valid. Any output = errors to fix.
-
Run inspections:
docker run -it --rm -v $PWD:/usr/local/structurizr structurizr/structurizr inspect -workspace workspace.dsl -severity error,warningChecks model consistency: missing descriptions, orphaned elements, broken relationships. Exit code = violation count.
-
Export to verify rendering:
# PlantUML (human-readable, good for review) docker run -it --rm -v $PWD:/usr/local/structurizr structurizr/structurizr export -workspace workspace.dsl -format plantuml -output diagrams/ # Mermaid (renders in GitHub/GitLab markdown) docker run -it --rm -v $PWD:/usr/local/structurizr structurizr/structurizr export -workspace workspace.dsl -format mermaid -output diagrams/ # Static HTML (interactive, for sharing) docker run -it --rm -v $PWD:/usr/local/structurizr structurizr/structurizr export -workspace workspace.dsl -format static -output site/
-
Visual review with Structurizr Local:
docker run -it --rm -p 8080:8080 -v $PWD:/usr/local/structurizr structurizr/structurizr local
Open http://localhost:8080 to inspect diagrams interactively.
| Mistake | Fix |
|---|---|
Using !identifiers flat with dot-paths |
Switch to !identifiers hierarchical |
| Defining relationships outside model scope | All relationships must be inside model {} or an element block |
| Missing technology on containers | Containers should specify technology (3rd param) |
| Component without parent container | Components must be inside a container block |
| Dynamic view steps referencing non-existent elements | All participants must exist in the model first |
| Forgetting deployment environment name | deployment system "Production" "key" "title" — env name is required |
| Nested groups at different abstraction levels | Groups only work within same level (people+systems, containers, or components) |
| Export to PNG/SVG without Chrome | PNG/SVG export needs a browser; use PlantUML/Mermaid for CI/CD |
| Not running validate before export | Always validate first — export may silently produce broken diagrams |
When generating Structurizr DSL from source code, follow this process:
- What are the main systems/services? →
softwareSystem - Who are the external actors? →
person(users, admins, external systems) - What are the data stores? →
containerwith database technology - What are the communication patterns? → relationships with technology strings
- What's the deployment topology? →
deploymentEnvironment
| Code Artifact | C4 Element | Example |
|---|---|---|
| HTTP server / API service | container (tech: "Node.js/Express") |
REST API, GraphQL server |
| Web app / SPA | container (tech: "React/TypeScript") |
Frontend, admin panel |
| Database | container (tech: "PostgreSQL") |
RDS, MongoDB, DynamoDB |
| Message queue | container (tech: "RabbitMQ") |
SQS, Kafka, Redis Streams |
| Cache | container (tech: "Redis") |
ElastiCache, Memcached |
| Module / package | component |
auth module, payment module |
| Docker container | containerInstance in deployment |
not a model element |
| External API | softwareSystem with "External" tag |
Stripe, SendGrid, AWS S3 |
| CLI tool | container (tech: "CLI/Python") |
migration scripts |
| Pattern | Relationship Technology |
|---|---|
| REST API calls | "REST/JSON over HTTPS" |
| GraphQL | "GraphQL over HTTPS" |
| gRPC | "gRPC" |
| Database queries | "JDBC", "SQL", "MongoDB Protocol" |
| Message publishing | "AMQP", "Kafka Protocol" |
| Redis operations | "Redis Protocol" |
| File I/O | "S3 API", "File System" |
enterprise "Org"
├── softwareSystem "Core Platform"
│ ├── container "Web App" (React)
│ ├── container "API" (Node.js)
│ │ ├── component "Auth Controller"
│ │ ├── component "Order Service"
│ │ └── component "Data Access Layer"
│ ├── container "Database" (PostgreSQL)
│ └── container "Cache" (Redis)
├── softwareSystem "External Service" (External)
└── person "End User"
- System Context — always generate first; shows the big picture
- Container — for systems with 2+ containers; shows internal structure
- Component — for containers with 3+ components; shows module structure
- Dynamic — for key user flows or API call sequences
- Deployment — when infrastructure topology matters
- Technology stack:
package.json,Dockerfile,go.mod,Cargo.toml, import statements - API endpoints: route definitions, OpenAPI specs, controller methods
- Database schemas: migration files, ORM models
- Team ownership:
CODEOWNERS, directory structure,@authorannotations - Environment configs:
.env,docker-compose.yml, Terraform files, Helm charts
What kind of diagram?
├─ Interaction flow / sequence ──→ dynamic view
├─ Infrastructure / deployment ──→ deployment view
├─ System overview ──→ systemlandscape or systemContext
├─ Service decomposition ──→ container view
└─ Module internals ──→ component view
What element type?
├─ User / person ──→ person
├─ Web UI / SPA ──→ container (tech: "React" etc.)
├─ API / microservice ──→ container (tech: "Node.js" etc.)
├─ Internal module ──→ component
├─ Database / store ──→ container (tech: "PostgreSQL" etc.)
├─ Message broker ──→ container (tech: "RabbitMQ" etc.)
├─ External system ──→ softwareSystem + tag "External"
└─ Infrastructure ──→ infrastructureNode or deploymentNode
workspace "Online Bookstore" "An online bookstore system" {
!identifiers hierarchical
model {
customer = person "Customer" "A user who purchases books"
admin = person "Admin" "Manages inventory and orders"
enterprise "BookCo" {
bookstore = softwareSystem "Online Bookstore" "Allows customers to browse and purchase books" {
web = container "Web Application" "Single-page application" "React/TypeScript" {
app = component "App" "Root component" "React"
catalog = component "Catalog View" "Book browsing" "React"
cart = component "Cart View" "Shopping cart" "React"
checkout = component "Checkout View" "Payment flow" "React"
}
api = container "API Server" "REST API backend" "Node.js/Express" {
authCtrl = component "Auth Controller" "Login/register" "Express"
catalogCtrl = component "Catalog Controller" "Book search" "Express"
orderCtrl = component "Order Controller" "Order management" "Express"
service = component "Service Layer" "Business logic" "TypeScript"
repo = component "Repository" "Data access" "TypeScript"
}
db = container "Database" "Persistent storage" "PostgreSQL"
cache = container "Cache" "Session and search cache" "Redis"
search = container "Search Engine" "Full-text book search" "Elasticsearch"
}
crm = softwareSystem "CRM" "Customer management" "Internal"
}
stripe = softwareSystem "Stripe" "Payment processing" "External"
// Relationships
customer -> bookstore.web "Browses and purchases" "HTTPS"
admin -> bookstore.api "Manages inventory" "HTTPS"
bookstore.web -> bookstore.api "API calls" "REST/JSON"
bookstore.api -> bookstore.db "Reads/writes" "JDBC"
bookstore.api -> bookstore.cache "Caches" "Redis Protocol"
bookstore.api -> bookstore.search "Searches" "REST"
bookstore.api -> stripe "Processes payments" "HTTPS"
bookstore -> crm "Syncs customers" "REST"
// Component relationships
bookstore.web.app -> bookstore.web.catalog
bookstore.web.app -> bookstore.web.cart
bookstore.web.app -> bookstore.web.checkout
bookstore.web.checkout -> bookstore.api "Submits order" "REST/JSON"
bookstore.api.catalogCtrl -> bookstore.api.service
bookstore.api.orderCtrl -> bookstore.api.service
bookstore.api.authCtrl -> bookstore.api.service
bookstore.api.service -> bookstore.api.repo
bookstore.api.repo -> bookstore.db "Queries" "JDBC"
// Deployment
deploymentEnvironment "Production" {
deploymentNode "AWS" {
deploymentNode "CloudFront" {
infraNode "CDN" "Static asset delivery" "CloudFront"
}
deploymentNode "ECS" {
containerInstance bookstore.web
containerInstance bookstore.api
}
deploymentNode "RDS" {
containerInstance bookstore.db
}
deploymentNode "ElastiCache" {
containerInstance bookstore.cache
}
deploymentNode "OpenSearch" {
containerInstance bookstore.search
}
}
}
}
views {
systemlandscape "landscape" "System Landscape" {
include *
autoLayout lr
}
systemContext bookstore "context" "System Context" {
include *
autoLayout tb
}
container bookstore "containers" "Container Diagram" {
include *
autoLayout lr
}
component bookstore.api "api-components" "API Components" {
include *
autoLayout tb
}
component bookstore.web "web-components" "Web Components" {
include *
autoLayout tb
}
dynamic bookstore "purchase" "Purchase Flow" {
customer -> bookstore.web "Opens book page"
bookstore.web -> bookstore.api "GET /books/:id" "REST"
bookstore.api -> bookstore.search "Search" "REST"
bookstore.api -> bookstore.db "Load book" "JDBC"
bookstore.web <- bookstore.api "Book details" "REST"
customer -> bookstore.web "Adds to cart"
customer -> bookstore.web "Proceeds to checkout"
bookstore.web -> bookstore.api "POST /orders" "REST"
bookstore.api -> stripe "Charge card" "HTTPS"
bookstore.api -> bookstore.db "Save order" "JDBC"
bookstore.web <- bookstore.api "Order confirmation" "REST"
autoLayout lr
}
deployment bookstore "Production" "prod" "Production Deployment" {
include *
autoLayout lr
}
styles {
element "Element" {
background #438dd5
color #ffffff
}
element "Person" {
shape Person
background #08427b
}
element "Software System" {
background #1168bd
}
element "External System" {
background #999999
}
element "Container" {
background #438dd5
}
element "Component" {
background #85bbf0
color #000000
}
element "Database" {
shape Cylinder
}
element "Cache" {
shape Cylinder
}
element "Search Engine" {
shape Cylinder
}
relationship "Relationship" {
routing Orthogonal
}
}
themes default
}
}| Topic | URL |
|---|---|
| DSL Language Reference | https://docs.structurizr.com/dsl/language |
| DSL Tutorial | https://docs.structurizr.com/dsl/tutorial |
| DSL Cookbook | https://docs.structurizr.com/dsl/cookbook |
| Pattern Catalog | https://docs.structurizr.com/dsl/pattern-catalog |
| Commands Reference | https://docs.structurizr.com/commands |
| Export Formats | https://docs.structurizr.com/export |
| Workspace Inspections | https://docs.structurizr.com/workspaces/inspections |
| Playground (try online) | https://playground.structurizr.com |
| Structurizr Local (Docker) | https://docs.structurizr.com/local |
| C4 Model Official Site | https://c4model.com |