D2

D2 is the newest language here and it shows in the ergonomics: nesting with braces, sensible defaults, and layout engines that produce diagrams which look designed rather than generated.

It suits architecture diagrams particularly well, because nesting maps directly onto boundaries.


#What it is good at

  • Architecture diagrams with grouping: accounts, VPCs, namespaces.

  • Diagrams you want to look good with no styling effort.

  • Sequence diagrams and SQL table shapes, which it handles natively.


#What it draws

Diagram

Syntax starts with

Shapes

name: Label { shape: cylinder }

Containers

parent: { child: Label }

Connections

a -> b: label

SQL tables

name: { shape: sql_table; id: int {constraint: primary_key} }

Direction

direction: right


#A worked example

Containers, a SQL table shape and labelled edges:

D2

The source, which you can paste into a new diagram and edit:

direction: right

client: Client

platform: Platform {
  api: API
  worker: Worker

  db: orders {
    shape: sql_table
    id: uuid {constraint: primary_key}
    customer_id: uuid {constraint: foreign_key}
    status: text
    total: numeric
  }
}

client -> platform.api: HTTPS
platform.api -> platform.db: INSERT
platform.api -> platform.worker: enqueue
platform.worker -> platform.db: UPDATE

#A few things that catch people out

  • Nesting is the main idea. Use containers for boundaries rather than drawing boxes.

  • Names are identifiers; the label after the colon is what is displayed.

  • D2 chooses its own layout. For pixel placement you still want draw.io.

  • An icon: can point at any web address, and Capable's rendering service fetches it when it draws the diagram. If an icon cannot be fetched, the diagram still renders and that icon is left blank. The built-in D2 templates use icons hosted by Capable, so they never depend on another site. See Domains we connect to.



Learn one properly. Borrow the rest when you need them.