Model
The model describes architecture as a set of hierarchical elements and any relationships among them.
Element
Section titled “Element”Element is a basic building block. It represents a logical part of the architecture.
Any element must have a kind and a name (identifier):
specification { element actor element service}
model { // element of kind 'actor' with the name 'customer' actor customer // element of kind 'service' named as 'cloud' service cloud
// also possible with '=' and the name goes first cloud = service}Element name is required for references.
It can contain letters, digits, hyphens and underscore, but can’t start with a digit or contain .
| name | valid |
|---|---|
| api | ✅ |
| Api2 | ✅ |
| _api | ✅ |
| __Api-1 | ✅ |
| 1api | ⛔️ |
| a.pi | ⛔️ |
Element Properties
Section titled “Element Properties”specification { element softwareSystem}model { // Title can be inlined saas = softwareSystem 'SaaS'
// or nested saas = softwareSystem { title 'SaaS'
// You can use `:` (optional) title: 'SaaS' }
// If title is not specified, name will be used by default saas = softwareSystem}Description
Section titled “Description”model { // Can be inlined saas = softwareSystem 'SaaS' 'Provides services to customers'
// or nested saas = softwareSystem { title 'SaaS' description 'Provides services to customers' }}Element may have a short summary (optional, falls back to description):
model { saas = softwareSystem { title 'SaaS' summary 'Provides services to customers' description ' Detailed description ... ' }}If summary is provided, it will be shown on the diagram, and description in the details dialog.
If you don’t provide description, summary will be used.
For inlined definition:
model { // [title] [summary] saas = softwareSystem 'SaaS' 'Provides services to customers' { description ' Detailed description ... ' }}Technology
Section titled “Technology”model { api = service { technology 'REST' }
// Structurizr DSL style: // <name> = softwareSystem [title] [summary] [technology] saas = softwareSystem 'SaaS' 'Provides services to customers' 'SaaS'}Element tags are defined in a nested block and must come first, before any properties:
model { appV1 = application 'App v1' { #deprecated description 'Old version of the application' }
// multiple tags appV2 = application { #next, #serverless #team2 title 'App v2' }
appV3 = application { title 'App v3' #team3 // ⛔️ Error: tags must be defined first }}Element may have multiple links:
model { bastion = application 'Bastion' { // External link link https://any-external-link.com
// With label link https://github.com/likec4/likec4 'Repository'
// or any URI link ssh://bastion.internal 'SSH'
// or relative link to navigate to sources link ../src/index.ts#L1-L10 }}Metadata
Section titled “Metadata”Element metadata is a set of key-value pairs, defined in a nested block:
model { app = application 'App' { metadata { prop1 'value1' prop2 ' apiVersion: apps/v1 kind: StatefulSet metadata: name: app-statefulset spec: {} ' prop3 '{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" } } }' } }}Only string values are allowed, but you can use JSON or YAML format for complex data.
Array Values
Section titled “Array Values”You can also use arrays for metadata values using array literal syntax:
model { app = application 'App' { metadata { tags ['frontend', 'react', 'typescript'] environments ['dev', 'staging', 'prod'] version '2.1.0' } }}Mixed single and array values are supported in the same metadata block:
model { api = service 'API Gateway' { metadata { version '3.2.1' maintainer 'Platform Team' tags ['backend', 'gateway', 'microservice'] regions ['us-east-1', 'eu-west-1'] critical true } }}Here are more examples showing various mixed metadata patterns:
model { // E-commerce application with mixed metadata types frontend = application 'Frontend App' { metadata { framework 'React' version '18.2.0' features ['shopping-cart', 'user-auth', 'payment', 'search'] deployment_targets ['staging', 'production'] team_lead 'Alice Johnson' developers ['Bob Smith', 'Carol Davis', 'David Wilson'] release_cycle 'weekly' supported_browsers ['Chrome', 'Firefox', 'Safari', 'Edge'] accessibility_level 'WCAG 2.1 AA' has_mobile_app true } }
// Database service with operational metadata database = service 'PostgreSQL Cluster' { metadata { engine 'PostgreSQL' version '15.3' instances ['primary', 'replica-1', 'replica-2'] backup_schedule 'daily' backup_retention_days '30' monitoring_endpoints ['metrics', 'logs', 'traces'] alert_channels ['slack', 'email', 'pagerduty'] maintenance_window 'Sunday 2-4 AM UTC' data_classification 'sensitive' encryption_at_rest true } }
// Microservice with complex deployment metadata payment = service 'Payment Service' { metadata { language 'Go' version '2.1.4' port '8080' health_check_path '/health' dependencies ['database', 'redis', 'external-payment-api'] environments ['dev', 'test', 'stage', 'prod'] scaling_policy 'auto' min_replicas '2' max_replicas '10' circuit_breaker_enabled true rate_limits ['1000/minute', '100/second'] compliance_standards ['PCI-DSS', 'SOC2'] } }}Metadata Properties Behavior
Section titled “Metadata Properties Behavior”Alphabetic Ordering: Metadata properties are automatically sorted alphabetically when displayed in element details, regardless of the order they are defined in the DSL. This ensures consistent presentation across all elements.
Property Duplications: When the same property name is defined multiple times within a metadata block, all values are collected into an array, preserving their order of definition:
model { service = component 'Payment Service' { metadata { version '1.0.0' // First value version '2.0.0' // Second value // Result: version: ['1.0.0', '2.0.0']
owner ['team-a', 'team-b'] // First: array values owner 'team-c' // Second: single value // Result: owner: ['team-a', 'team-b', 'team-c']
tags 'primary' // First: single value tags ['backend', 'critical'] // Second: array values // Result: tags: ['primary', 'backend', 'critical']
ports ['8080', '9090'] // First: array values ports ['3000', '4000'] // Second: array values // Result: ports: ['8080', '9090', '3000', '4000'] } }}This behavior applies to all duplicate keys.
All metadata properties are displayed alphabetically, regardless of definition order.
model { api = service 'API Gateway' { metadata { version '3.2.1' maintainer 'Platform Team' tags ['backend', 'gateway', 'microservice'] regions ['us-east-1', 'eu-west-1'] critical true } }}Here are more examples showing various mixed metadata patterns:
model { // E-commerce application with mixed metadata types frontend = application 'Frontend App' { metadata { framework 'React' version '18.2.0' features ['shopping-cart', 'user-auth', 'payment', 'search'] deployment_targets ['staging', 'production'] team_lead 'Alice Johnson' developers ['Bob Smith', 'Carol Davis', 'David Wilson'] release_cycle 'weekly' supported_browsers ['Chrome', 'Firefox', 'Safari', 'Edge'] accessibility_level 'WCAG 2.1 AA' has_mobile_app true } }
// Database service with operational metadata database = service 'PostgreSQL Cluster' { metadata { engine 'PostgreSQL' version '15.3' instances ['primary', 'replica-1', 'replica-2'] backup_schedule 'daily' backup_retention_days '30' monitoring_endpoints ['metrics', 'logs', 'traces'] alert_channels ['slack', 'email', 'pagerduty'] maintenance_window 'Sunday 2-4 AM UTC' data_classification 'sensitive' encryption_at_rest true } }
// Microservice with complex deployment metadata payment = service 'Payment Service' { metadata { language 'Go' version '2.1.4' port '8080' health_check_path '/health' dependencies ['database', 'redis', 'external-payment-api'] environments ['dev', 'test', 'stage', 'prod'] scaling_policy 'auto' min_replicas '2' max_replicas '10' circuit_breaker_enabled true rate_limits ['1000/minute', '100/second'] compliance_standards ['PCI-DSS', 'SOC2'] } }}model { api = service 'API Gateway' { metadata { version '3.2.1' maintainer 'Platform Team' tags ['backend', 'gateway', 'microservice'] regions ['us-east-1', 'eu-west-1'] critical true } }}model { api = service 'API Gateway' { metadata { version '3.2.1' maintainer 'Platform Team' tags ['backend', 'gateway', 'microservice'] regions ['us-east-1', 'eu-west-1'] critical true } }}Using Markdown
Section titled “Using Markdown”You can use markdown in description (and summary) with triple quotes:
model { mobile = application { title 'Mobile Application' description ''' ### Multi-platform application
[React Native](https://reactnative.dev) ''' }
web = application { description """ ### Web Application
> Provides services to customers through > the web interface.
| checks | | | :--------- | :-- | | check 1 | ✅ | | check 2 | ⛔️ | | check 3 | ✅ | """ }}Structuring Model
Section titled “Structuring Model”Any element is a container and can contain other elements.
This way you define the structure and internals of the element.
model { // service1 has backend and frontend service service1 { component backend { // backend has api component api } component frontend }
// or use '=' service2 = service { backend = component { api = component } frontend = component }}Nested elements are “namespaced”, the parent name is used as a prefix.
So, the model above has the elements with these fully qualified names:
service1service1.backendservice1.backend.apiservice1.frontend
and:
service2service2.backendservice2.backend.apiservice2.frontend