mdd
DocsUse CasesGitHubOpen App
mdd-markdown-diagram

Two views of the same system. One source of truth.

mdd turns a small JSON model of boxes and relationships — or participants and messages — into a perfectly-aligned Unicode ASCII diagram, and keeps both living together in your Markdown.

The gap it bridges

Humans read hierarchy and relationships best as a picture. AI reads and edits structured data best. Markdown Diagram gives each audience the representation it is good at — and generates both from the same model, so the two can never disagree.

Hand-drawn ASCII breaks: borders drift out of alignment and connectors miss their targets. Prose descriptions of a system silently fall out of date. mdd fixes both by making the diagram structured data and letting a program — not a person or a model eyeballing characters — compute the layout.

How it works

If you are human

Open the web editor and work on a canvas: place boxes, drag them into rows, and draw connections between them. Drag from empty canvas to marquee-select several boxes at once (hold Space, or use the middle mouse button, to pan instead). Set labels, border weights, shapes (rectangle or decision diamond), and arrow directions directly — no JSON by hand. The canvas renders the exact same Unicode ASCII the engine produces, live as you edit. Export the Markdown — with the diagram embedded in its mdd block — plus the JSON sidecar, ready to drop into your repo. The CLI can splice the same block into source-file comments too (// , # , -- ) — prefix-aware and idempotent — so a diagram can live in a header comment right next to the code it describes. In the editor, pick a comment prefix under the Diagram panel's settings and the export panel shows — and copies — that comment-style block instead of Markdown.

Start a sequence diagram from the new-tab menu instead, and the same canvas switches to a lifeline layout: a Participant tool for the columns, Message and Reply tools for the arrows between them, and drag-to-reorder for both time (arrows) and columns (headers) — see Two diagram kinds below.

<!-- mdd:begin id=arch src=arch.diagram.json -->
```
           ┌───────────────┐
           │ Load Balancer │
           └───────┬───────┘
         ┌─────────┴────────┐
         │                  │
 ┌───────▼──────┐   ┌───────▼──────┐
 │ API Server A │   │ API Server B │
 └──────────────┘   └──────────────┘
```
[diagram source](arch.diagram.json)
<!-- mdd:end -->

If you are an AI

Edit the JSON — boxes, rows, connections — which is the source of truth. The engine computes the layout (not a model eyeballing characters) and renders Unicode box-drawing ASCII that displays identically in GitHub, terminals, and plain-text editors. Both live inside a delimited mdd block in a Markdown file; regenerating never disturbs the surrounding prose, and the ASCII is a generated projection that is never parsed back.

{
  "version": 1,
  "boxes": [
    { "id": "lb",   "label": "Load Balancer", "row": 0, "style": 2,
      "connections": [
        { "to": "api1", "style": 2, "arrow": "to" },
        { "to": "api2", "style": 2, "arrow": "to" }
      ] },
    { "id": "api1", "label": "API Server A", "row": 1, "style": 2, "connections": [] },
    { "id": "api2", "label": "API Server B", "row": 1, "style": 2, "connections": [] }
  ]
}

When something can't be done

The editor never fails silently. Structural problems (an empty label, a broken connection) appear in the messages strip below the canvas; render warnings — like a connector label that has no room to be drawn — appear there too, in amber. An edit the engine rejects (shrinking a table over a cell that still has text, deleting a table's last row) shows a brief notice explaining why, and controls that would always be rejected are disabled up front. If autosave to browser storage stops working you'll see "Save failed" in the top bar. If the editor itself crashes, a reload screen restores your last autosaved state.

Who it's for

  • Teams keeping architecture diagrams in README or agents.md that must render everywhere.
  • AI agents that need to emit and update diagrams reliably instead of drawing characters by hand.
  • Anyone who wants diagrams-as-data: diffable, reviewable, and regenerable.

Two diagram kinds

mdd has two diagram kinds: box diagrams for structure and flow (systems, schemas, trust boundaries, pipelines, runbooks) and sequence diagrams for behavior over time (call flows, handshakes, incident timelines) — participants with lifelines, messages ordered top to bottom by time:

 ┌────────┐      ┌────────┐
 │ Client │      │ Server │
 └────────┘      └────────┘
      │               │
      │ login(creds)  │
      │──────────────▶│
      │               │
      │ session token │
      │◀┄┄┄┄┄┄┄┄┄┄┄┄┄┄│
      │               │

The CLI renders both from JSON the same way, and the editor on this site supports both: the new-tab menu offers Box or Sequence, inserting a diagram block into a local file asks which kind to create, and a kind: "sequence" sidecar imports and opens exactly like a box diagram. See the ASCII sequence diagrams use case for a fuller worked example.

  • Select, Participant, Message, and Reply tools build the diagram directly on the canvas — no JSON by hand.
  • Two clicks on a lifeline draw a call; the Reply tool draws the dashed return. Clicking the same lifeline twice draws a self-message. Each new arrow lands at the bottom, so drawing them in order gives you that order.
  • Drag an arrow to reorder it in time, or drag a participant header to reorder the columns. A ghost copy tracks the pointer while you drag — sideways for a participant, up and down for an arrow — and the diagram reflows to preview where it will land.
  • Selecting an arrow is forgiving: it answers to a click anywhere in its row band — the label and the blank row above it included — not just the one row the arrow is drawn on.

Two ways to use it

  • The visual editor (this app) — place and connect boxes on a canvas.
  • The mdd CLI and programmatic API — for scripts, agents, and CI. See the Docs.