Mermaid ER Diagram: Complete Syntax Guide with Examples
Mermaid ER diagrams let you document database schemas and data models in plain text, inside the same Markdown files as your code documentation. Search interest in "mermaid er diagram" has grown 84% year-over-year (DataForSEO, 2026) — development teams are moving away from screenshot-based database diagrams toward version-controlled, text-based alternatives. MacMD Viewer ($19.99, native macOS SwiftUI app) renders Mermaid ER diagrams locally in .md files with no plugins or internet connection. This guide covers the full erDiagram syntax with working examples you can copy directly into your documentation.
TL;DR: Start with
erDiagram, define entities usingENTITY { type name PK }, connect them with||--o{for one-to-many relationships. Use--for identifying relationships and..for non-identifying. Preview locally with MacMD Viewer or online at mermaid.live.
What Is a Mermaid ER Diagram and When Should You Use It?
A Mermaid ER diagram is a text-based entity-relationship diagram that describes database tables, their columns, and how they relate to each other. You write it inside a ```mermaid code fence starting with erDiagram, and any Mermaid renderer produces a visual diagram from that text.
ER diagrams are useful in three primary contexts:
- Database design — sketch the schema before writing migrations, catch relationship mistakes early
- Technical documentation — explain the data model to new engineers without maintaining a separate diagram file
- Code review — include an ER diagram in a PR to show how a migration changes the schema
Compared to dedicated tools like dbdiagram.io or draw.io, the Mermaid approach has one decisive advantage: the diagram lives in your repository as plain text, so Git tracks every change. When a column is renamed or a relationship is added, the diff shows exactly what changed — you never end up with a stale PNG that no longer matches the actual schema.
ER diagrams have been stable in Mermaid since v8, and every current renderer supports them. For related Mermaid diagram types, see the Mermaid flowchart syntax guide and the Mermaid sequence diagram guide.
How Do You Write Basic Mermaid ER Diagram Syntax?
An ER diagram starts with erDiagram, followed by entity blocks and relationship lines. Here is the minimal structure that renders a valid diagram:
erDiagram
USER {
int id PK
string email UK
string name
date createdAt
}
POST {
int id PK
int userId FK
string title
string body
datetime publishedAt
}
USER ||--o{ POST : "writes"This produces two entity boxes connected by a one-to-many line labeled "writes". The USER entity has four attributes: an integer primary key, a unique email, a name, and a creation date. The POST entity has a foreign key back to USER.
Every entity block follows the same pattern:
ENTITY_NAME {
type attributeName optionalKey
type attributeName optionalKey
}
Entity names are typically uppercase by convention, though Mermaid accepts any case. Attribute types are free-form strings — Mermaid does not validate them against a schema, so you can write varchar(255), string, or TEXT and the diagram renders identically. Stick to a consistent set of types across your codebase.
Supported Attribute Types
Common types used in Mermaid ER diagrams:
| Type | Use Case |
|---|---|
int | Integer identifier or counter |
bigint | Large integer (user IDs at scale) |
string | Short text (names, slugs, status) |
text | Long text (body content, descriptions) |
boolean | True/false flags |
float / decimal | Numeric values with decimals |
date | Date without time |
datetime | Full timestamp |
uuid | UUID primary key |
json | JSON blob column |
How Do You Add Keys to ER Diagram Attributes?
Mermaid supports three key markers that appear after the attribute name. Add them as a suffix with a space:
| Marker | Meaning |
|---|---|
PK | Primary key |
FK | Foreign key |
UK | Unique key (unique constraint) |
An attribute can have multiple markers if needed — int id PK is the most common pattern, but string email UK marks a unique constraint and int orderId FK marks a foreign key reference.
erDiagram
CUSTOMER {
uuid id PK
string email UK
string firstName
string lastName
date createdAt
}
ORDER {
uuid id PK
uuid customerId FK
decimal totalAmount
string status
datetime placedAt
}
CUSTOMER ||--o{ ORDER : "places"Comments use %% at the start of a line, identical to other Mermaid diagram types:
%% This diagram documents the e-commerce schema v2
erDiagram
PRODUCT {
int id PK
string sku UK
}
What Does the Relationship Notation Mean?
The relationship line syntax is the most distinctive part of Mermaid ER diagrams. The notation ||--o{ looks cryptic at first, but each character has a specific meaning that maps directly to standard crow's foot notation.
A relationship line has five components:
ENTITY1 LEFT_MARKER -- RIGHT_MARKER ENTITY2 : "label"
The -- (double dash) is the line style. Use -- for an identifying relationship (the child depends on the parent for its identity) or .. for a non-identifying relationship (both entities exist independently).
Cardinality Markers
Each side of the line takes a two-character cardinality marker:
| Marker | Meaning | Description |
|---|---|---|
|| | Exactly one | Mandatory, singular |
o| | Zero or one | Optional, singular |
|{ | One or more | Mandatory, plural |
o{ | Zero or more | Optional, plural |
Reading ||--o{ from left to right: exactly one (on the left entity) — identifying relationship — zero or more (on the right entity). This is a standard one-to-many.
Full Notation Reference
| Notation | Cardinality | Real-World Example |
|---|---|---|
||--|| | One-to-one | USER has one PROFILE |
||--o| | One-to-zero-or-one | USER has optional BILLING_ADDRESS |
||--o{ | One-to-zero-or-many | CUSTOMER places zero or more ORDERS |
||--|{ | One-to-one-or-many | ORDER contains one or more ORDER_ITEMS |
o{--o{ | Many-to-many | PRODUCT belongs to many CATEGORIES |
||..o{ | Non-identifying one-to-many | POST has zero or more COMMENTS |
The label after the colon is required in Mermaid ER syntax. Wrap it in double quotes: : "places", : "contains", : "belongs to". The label describes the relationship from the perspective of the left entity.
What Does a Real-World ER Diagram Look Like?
Here is a complete e-commerce schema covering the four core tables most production systems share: customers, products, orders, and order line items.
erDiagram
CUSTOMER {
uuid id PK
string email UK
string firstName
string lastName
string phone
date createdAt
}
ADDRESS {
uuid id PK
uuid customerId FK
string street
string city
string country
string postalCode
boolean isDefault
}
PRODUCT {
uuid id PK
string sku UK
string name
text description
decimal price
int stockQuantity
boolean isActive
}
ORDER {
uuid id PK
uuid customerId FK
uuid shippingAddressId FK
string status
decimal subtotal
decimal shippingCost
decimal totalAmount
datetime placedAt
}
ORDER_ITEM {
uuid id PK
uuid orderId FK
uuid productId FK
int quantity
decimal unitPrice
decimal lineTotal
}
CUSTOMER ||--o{ ADDRESS : "has"
CUSTOMER ||--o{ ORDER : "places"
ADDRESS ||--o{ ORDER : "ships to"
ORDER ||--|{ ORDER_ITEM : "contains"
PRODUCT ||--o{ ORDER_ITEM : "included in"This diagram captures the full purchase flow: customers own addresses and place orders, orders are shipped to one address and contain one or more items, and each item references the product it sold. The ORDER_ITEM table uses identifying relationships (--) because a line item cannot exist without its parent order. The ADDRESS to ORDER link is also identifying for the same reason.
For a blog platform, the schema looks like this:
erDiagram
USER {
int id PK
string username UK
string email UK
string passwordHash
datetime createdAt
}
POST {
int id PK
int authorId FK
string title
string slug UK
text body
string status
datetime publishedAt
}
COMMENT {
int id PK
int postId FK
int authorId FK
text body
datetime createdAt
}
TAG {
int id PK
string name UK
string slug UK
}
POST_TAG {
int postId FK
int tagId FK
}
USER ||--o{ POST : "writes"
USER ||--o{ COMMENT : "authors"
POST ||--o{ COMMENT : "has"
POST ||--o{ POST_TAG : "tagged with"
TAG ||--o{ POST_TAG : "applied to"The POST_TAG junction table implements the many-to-many relationship between posts and tags. Both foreign keys together form the composite primary key, which is common for join tables.
What Are the Most Common ER Diagram Mistakes?
Four mistakes appear repeatedly in Mermaid ER diagrams written by developers new to the syntax.
Wrong relationship direction. The label should read naturally from left to right: CUSTOMER ||--o{ ORDER : "places" — a customer places orders, not the other way around. Reversing the entities reverses the cardinality meaning, which produces a diagram that renders but communicates the opposite of the intended relationship.
Missing relationship label. The label after : is not optional in Mermaid's ER syntax. Omitting it throws a parse error. Use a short verb phrase: "has", "contains", "belongs to".
Confusing -- and ... Use -- (identifying) when the child row has no meaning without the parent — an order item without an order is meaningless. Use .. (non-identifying) when both can exist independently — a product exists even if no orders have ever included it.
Spaces in entity names. Entity names cannot contain spaces. Use ORDER_ITEM or OrderItem, not ORDER ITEM. The underscore convention matches SQL naming and is the most common pattern in the wild.
Where Do Mermaid ER Diagrams Render?
Mermaid ER diagrams render anywhere the Mermaid.js library is present:
| Platform | Notes |
|---|---|
| MacMD Viewer | Native macOS app, renders locally, no internet needed. Download here. |
| GitHub | Renders natively in .md files since 2022 — push your diagram, GitHub displays it. |
| GitLab | Built-in Mermaid rendering in Markdown files and wikis. |
| Notion | Use the /code block, select Mermaid as the language. |
| Confluence | Requires the Mermaid for Confluence plugin. See the Mermaid Confluence guide. |
| Mermaid Live Editor | Free browser playground at mermaid.live. Best for iterating. |
| Obsidian | Renders natively — no plugin needed. |
| VS Code | Use the Markdown Mermaid extension with Cmd+Shift+V. |
For a full comparison of browser-based options, see online Mermaid diagram tools. If you want to export diagrams as PNG or SVG files, the Mermaid live editor guide covers the export workflow. You can also use the Mermaid viewer roundup to compare dedicated rendering tools.
How Does Mermaid Compare to Dedicated ER Diagram Tools?
Dedicated tools like dbdiagram.io, draw.io, and Lucidchart offer richer visual editing: drag-and-drop layout control, auto-generated SQL from your schema, and export to multiple formats. For teams that need a polished standalone diagram, those tools are the right choice.
Mermaid wins when your diagram lives inside documentation. Three specific advantages:
- Version control — the diagram is a text file, so
git diffshows exactly what changed between schema versions. A PNG has no diff. - Documentation co-location — the schema lives next to the code in the same repository. No separate diagramming account, no broken links to external tools.
- Renderer ubiquity — GitHub, GitLab, Notion, Obsidian, and VS Code all render Mermaid natively. Your diagram is readable anywhere your Markdown file opens.
The tradeoff is layout control. Mermaid places entities automatically — you cannot manually position boxes. For large schemas (30+ tables), auto-layout produces cluttered output. In that case, split the schema into domain-specific sub-diagrams: one for user management, one for orders, one for inventory.
MacMD Viewer is the fastest local option on macOS: open a .md file and the ER diagram renders immediately. The QuickLook extension also renders Mermaid when you press Space on a .md file in Finder — useful when reviewing schema documentation without opening any app.
Conclusion
Mermaid ER diagram syntax is compact: declare erDiagram, define entities with typed attributes and key markers, connect them with cardinality notation. The ||--o{ relationship syntax covers every cardinality combination once you know that || means exactly-one, o| means zero-or-one, |{ means one-or-more, and o{ means zero-or-more. Use -- for identifying relationships and .. for non-identifying.
Copy the e-commerce or blog schema examples above, replace entity names and attributes with your own tables, and you have a working database diagram that lives in version control. Preview locally with MacMD Viewer for instant rendering on Mac, or iterate in the browser at mermaid.live. For more Mermaid diagram types, see the complete Mermaid diagram guide and the Mermaid flowchart syntax reference.
Continue reading with AI
Content licensed under CC BY 4.0. Cite with attribution to MacMD Viewer.