Choreo provides powerful tools for modeling, analyzing, and rendering system architectures, database designs, security boundaries, and code structures.
Choreo — System Architecture
Model systems with typed infrastructure nodes: databases, caches, services, queues, load balancers, networks, users, storage, compute, and managed databases. Use this for general service-level and system architecture diagrams.
alias Choreo
system =
Choreo.new()
|> Choreo.add_database(:db, label: "Postgres", kind: :postgres)
|> Choreo.add_cache(:cache, label: "Redis")
|> Choreo.add_service(:api, label: "API Gateway")
|> Choreo.connect(:api, :cache, cost: 5)
|> Choreo.connect(:api, :db, cost: 10)
# Analysis
{:ok, mst} = Choreo.Analysis.mst(system)
{:ok, order} = Choreo.Analysis.topological_sort(system)
# Render
dot = Choreo.to_dot(system, theme: :dark)
mermaid = Choreo.to_mermaid(system)Features: clusters with nesting (including typed VPC/subnet boundaries), dataflow edges, cost-weighted edges, MST, topological sort, SCC, theming, cross-diagram embedding and tracing.
graph TD
classDef default color:white
cache{{"Redis"}}
db[("Postgres")]
api[["API Gateway"]]
style cache fill:#f59e0b,stroke:#d78000
style db fill:#3b82f6,stroke:#1d64d8
style api fill:#10b981,stroke:#009b63
api --> cache
api --> db
linkStyle 0 stroke-width:2px,stroke:#64748b
linkStyle 1 stroke-width:2px,stroke:#64748bChoreo.Infrastructure — Cloud Network Topology
A domain-specific vocabulary layer on top of Choreo for modeling cloud network topologies with VPCs, subnets, compute instances, managed databases, and load balancers. It shares the same rendering pipeline and data model as Choreo but adds security-aware analysis rules.
Use Choreo.Infrastructure when you need:
- Typed cluster boundaries — VPCs, public subnets, and private subnets with security semantics
- Security audits — automatic checks for direct internet-to-private links, misplaced databases, and exposed storage
- Cloud vocabulary —
add_vpc/3,add_compute/3,add_managed_db/3,add_subnet_public/3, etc.
alias Choreo.Infrastructure
infra =
Infrastructure.new()
|> Infrastructure.add_vpc("vpc_main", label: "Production VPC")
|> Infrastructure.add_subnet_public("dmz", label: "Public DMZ", parent: "vpc_main")
|> Infrastructure.add_subnet_private("app", label: "App Tier", parent: "vpc_main")
|> Infrastructure.add_load_balancer(:alb, label: "ALB", cluster: "dmz")
|> Infrastructure.add_compute(:api, label: "API", cluster: "app")
|> Infrastructure.add_managed_db(:db, label: "Postgres RDS", cluster: "app")
|> Infrastructure.connect(:alb, :api)
|> Infrastructure.connect(:api, :db)
# Security audit
Choreo.Infrastructure.Analysis.validate(infra)
# => [] (or [{:error, ...}, {:warning, ...}] if violations found)Note: Choreo.Infrastructure is a thin wrapper over Choreo — it uses the same struct fields, rendering pipeline, and theming system. You can embed an Infrastructure diagram into a top-level Choreo diagram and it will render seamlessly.
Choreo.C4 — C4 Model Architecture
Model software architecture at multiple zoom levels — from system context down to components — in a single unified graph.
alias Choreo.C4
alias Choreo.C4.Analysis
c4 =
C4.new()
|> C4.add_person(:customer, label: "Customer")
|> C4.add_software_system(:banking,
label: "Internet Banking",
scope: :in,
description: "Allows customers to view balances and make payments"
)
|> C4.add_software_system(:mainframe,
label: "Mainframe Banking",
description: "Stores all core banking information"
)
|> C4.add_container(:web_app,
label: "Web Application",
technology: "JavaScript",
parent: :banking
)
|> C4.add_container(:api,
label: "API Application",
technology: "Elixir/Phoenix",
parent: :banking
)
|> C4.add_component(:accounts_ctx,
label: "Accounts Context",
technology: "Elixir",
parent: :api
)
|> C4.relationship(:customer, :banking, label: "Views account balances")
|> C4.relationship(:banking, :mainframe, label: "Gets account info")
# Zoom to a specific C4 level
C4.to_mermaid(Choreo.View.zoom(c4, level: 0)) # System Context
C4.to_mermaid(Choreo.View.zoom(c4, level: 1)) # Container diagram
C4.to_mermaid(Choreo.View.zoom(c4, level: 2)) # Component diagram
# Analysis
Analysis.missing_descriptions(c4)
Analysis.isolated_nodes(c4)
Analysis.validate(c4)Features: L1–L3 C4 modeling (System Context, Containers, Components), zoom-aware rendering, parent/child clustering, missing metadata detection, isolated node detection.
graph TD
classDef default color:white
banking["Internet Banking"]
customer(("Customer"))
mainframe["Mainframe Banking"]
style banking fill:#3b82f6,stroke:#1d64d8,stroke-width:3px
style customer fill:#f59e0b,stroke:#d78000
style mainframe fill:#64748b,stroke:#46566d
banking --> mainframe
customer --> banking
linkStyle 0 stroke-width:2px,stroke:#64748b
linkStyle 1 stroke-width:2px,stroke:#64748bChoreo.ThreatModel — STRIDE Threat Modeling
Extend dataflow diagrams with security semantics. Auto-generate STRIDE threats based on element types, trust boundaries, and encryption status.
alias Choreo.ThreatModel
alias Choreo.ThreatModel.Analysis
model =
ThreatModel.new()
|> ThreatModel.add_trust_boundary("internet", level: 0)
|> ThreatModel.add_trust_boundary("app", level: 2)
|> ThreatModel.add_external_entity(:user, boundary: "internet", label: "User")
|> ThreatModel.add_process(:api, boundary: "app", privilege: :admin, label: "API")
|> ThreatModel.add_data_store(:db, boundary: "app", sensitivity: :confidential, label: "DB")
|> ThreatModel.data_flow(:user, :api)
|> ThreatModel.data_flow(:api, :db, encrypted: true)
# Auto-generated threats
threats = Analysis.stride_threats(model)
# Security analysis
Analysis.exposed_data_stores(model)
Analysis.high_risk_processes(model)
Analysis.unencrypted_boundary_flows(model)
# Sequence diagram
ThreatModel.to_sequence(model) #=> Mermaid sequenceDiagram stringFeatures: automated STRIDE threat generation with severity scoring, trust-boundary crossing detection, exposed-data-store identification, high-risk process detection, encrypted-flow detection, sequence diagram generation.
graph LR
classDef default color:white
user["User"]
api(("API"))
db[("DB")]
style user fill:#64748b,stroke:#46566d,stroke-width:3px
style api fill:#3b82f6,stroke:#1d64d8
style db fill:#f59e0b,stroke:#d78000
subgraph app ["app"]
api
db
end
subgraph internet ["internet"]
user
end
user --> api
api --> db
linkStyle 0 stroke-width:2px,stroke:#64748b,stroke-dasharray:5 5
linkStyle 1 stroke-width:2px,stroke:#64748bChoreo.Domain — DDD & Event Storming Domain Modeling
Model complex domains using Event Storming syntax and Strategic Context Mapping. Declare bounded contexts, aggregates, commands, events, sagas/policies, and Scott Wlaschin-style algebraic data types (ADTs) and workflows.
alias Choreo.Domain
alias Choreo.Domain.Analysis
model =
Domain.new()
|> Domain.add_context_boundary("ordering", label: "Ordering Bounded Context")
|> Domain.add_aggregate(:order_agg, label: "Order Aggregate", parent: "ordering")
|> Domain.add_command(:place_order, label: "Place Order")
|> Domain.add_event(:order_placed, label: "Order Placed")
|> Domain.connect(:place_order, :order_agg, label: "handles")
|> Domain.connect(:order_agg, :order_placed, label: "publishes")
# Strategic Context Mapping
context_map =
Domain.new()
|> Domain.add_context(:ordering, label: "Ordering Service")
|> Domain.add_context(:billing, label: "Billing Service")
|> Domain.connect_contexts(:ordering, :billing, type: :acl, label: "Upstream -> Downstream")
# Render
mermaid = Domain.to_mermaid(model)Features: bounded contexts, aggregates, command-event separation, anti-corruption layers (ACL), algebraic data type tables (ADTs), workflows, strategic context maps, validation.
Choreo.ERD — Database Entity-Relationship Modeling
Model database schemas, validate data integrity constraints, render beautiful HTML-like tables or native Mermaid erDiagram syntaxes, and run advanced topological analysis.
alias Choreo.ERD
alias Choreo.ERD.Analysis
erd =
ERD.new()
|> ERD.add_table(:users, columns: [
%{name: :id, type: :integer, key: :pk},
%{name: :email, type: :varchar, comment: "unique email"}
])
|> ERD.add_table(:posts, columns: [
%{name: :id, type: :integer, key: :pk},
%{name: :user_id, type: :integer, key: :fk},
%{name: :title, type: :varchar}
])
|> ERD.add_table(:comments, columns: [
%{name: :id, type: :integer, key: :pk},
%{name: :post_id, type: :integer, key: :fk},
%{name: :body, type: :text}
])
|> ERD.add_relationship(:users, :posts, cardinality: :one_to_many, label: "writes")
|> ERD.add_relationship(:posts, :comments, cardinality: :one_to_many, label: "has")
# Topological Analysis
Analysis.shortest_join_path(erd, :users, :comments) #=> {:ok, [:users, :posts, :comments]}
Analysis.cycles(erd) #=> [] (no circular foreign keys!)
Analysis.orphans(erd) #=> []
Analysis.table_degrees(erd) #=> %{users: %{in: 0, out: 1, total: 1}, ...}Features: strict columns and relationship validation, customizable themed HTML record labels in DOT output, native Mermaid erDiagram generation, undirected BFS join path solver, DFS circular foreign key cycle detection, orphan and coupling metrics.
erDiagram
users {
integer id PK
varchar email "unique email"
}
posts {
integer id PK
integer user_id FK
varchar title
}
comments {
integer id PK
integer post_id FK
text body
}
users ||--o{ posts : "writes"
posts ||--o{ comments : "has"Choreo.UML — Class & Struct Diagrams
Model software module contracts, behaviors, protocols, structs, their fields, arities, and visibilities, and declare exact structural relations with visual parity.
alias Choreo.UML
uml =
UML.new()
|> UML.add_class(:user,
type: :struct,
label: "User Model",
fields: [
%{name: :id, type: :integer, visibility: :public},
%{name: :email, type: :string, visibility: :private}
],
functions: [
%{name: "authenticate", arity: 2, return: :boolean, visibility: :public}
]
)
|> UML.add_class(:auth_provider, type: :behavior)
|> UML.add_relationship(:user, :auth_provider, type: :realizes, label: "implements")
# Render to native Mermaid class diagram
UML.to_mermaid(uml, syntax: :class_diagram)Features: multi-compartment record tables, standard visibility markers (+, -, #), functional contracts, protocol realization, behavior adoption, lens focusing via Choreo.View.
classDiagram
direction TD
class user["User Model"] {
<<struct>>
+id integer
-email string
+authenticate(2) boolean
}
class auth_provider["auth_provider"] {
<<behavior>>
}
user ..|> auth_provider : implements