Markdown D2 diagram editor

Write a D2 diagram as text and see it drawn as you type. This is D2 itself, compiled to WebAssembly and running in your browser, so the result matches the D2 command line and nothing you type leaves your computer. The text sits in your Markdown as a ```d2 block. Free, no sign-up.

The first diagram takes a few seconds while D2 starts; after that it re-draws in a moment.

D2 syntax

D2 describes shapes and the connections between them. Name a shape to create it, give it a label after a colon, and join shapes with arrows. Settings go in braces after a shape, and # starts a comment. D2 lays everything out for you.

Shapes and connections

A connection is two shape names joined by ->, <-, <-> or --. Text after the colon labels it.

You write
browser -> server: request
server -> browser: page
server <-> cache
server -- logs
You get

Labels and shapes

A shape's name is its key; the text after the colon is what is shown. Set shape inside braces to change how it is drawn.

You write
user: Customer {shape: person}
web: Web server
db: Orders {shape: cylinder}
queue: Jobs {shape: queue}
user -> web -> db
web -> queue
You get

Containers

Shapes inside braces belong to the shape around them. Refer to a shape inside a container with a dot, as in cloud.api.

You write
direction: right
cloud: Cloud {
  lb: Load balancer
  api: API
  lb -> api
}
user -> cloud.lb
You get

SQL tables

The sql_table shape lists columns with their types and constraints, and connections can point at a single column.

You write
users: {
  shape: sql_table
  id: int {constraint: primary_key}
  name: varchar
}
orders: {
  shape: sql_table
  id: int {constraint: primary_key}
  user_id: int {constraint: foreign_key}
}
orders.user_id -> users.id
You get

Style

Every shape and connection has a style block for colours, dashes and more.

You write
draft -> review -> live
live.style.fill: "#e6f4ea"
review.style.stroke-dash: 3
draft.style.border-radius: 8
You get

Cheat sheet

Write this You get
aA box labelled a
a: Some textA box with a label
a -> bAn arrow from a to b
a <-> b, a -- bA two-way arrow, a plain line
a -> b: labelA labelled arrow
a -> b -> cA chain of arrows
a: {shape: cylinder}A database shape (also person, queue, cloud, oval, diamond, hexagon, document and more)
box: { a; b }A container holding a and b
box.a -> cConnect a shape inside a container
shape: sql_tableA database table with typed columns
a.style.fill: "#eef4ff"Fill colour (also stroke, stroke-dash, font-color)
direction: rightLay the diagram out left to right
# noteA comment, not drawn

Not covered here: @import of other files, the TALA layout engine and icons loaded from web addresses.

Something not working? Let us know.