Mermaid Class Diagram: The Eight Relationships and When to Use Which
Short answer: start the block with `classDiagram`, declare each class with `class Name { }`, put fields and methods inside the braces with `+` for public and `-` for private, and connect classes with one of eight relationship arrows. `<|--` is inheritance, `*--` is composition, `o--` is aggregation, `-->` is association.
The grammar is an afternoon. The judgment is what separates a class diagram that explains a system from one that reproduces the source code in a less readable font.
What does Mermaid class diagram syntax look like?
``` classDiagram class Order { +String id +OrderStatus status -Money subtotal +addLine(SkuLine line) void +total() Money } class SkuLine { +String sku +int quantity } class Customer { +String id +String email } class PaymentGateway { <<interface>> +charge(Money amount) Receipt }
Customer "1" --> "" Order : places Order "1" -- "*" SkuLine : contains Order ..> PaymentGateway : uses ```
Four things are happening there.
Members. A field is a type and a name; a method is a name, parentheses, optional parameters, and an optional return type. The leading symbol is visibility: `+` public, `-` private, `#` protected, `~` package.
Annotations. `<<interface>>` inside the braces marks the class as an interface. `<<abstract>>`, `<<enumeration>>`, and `<<service>>` work the same way. They are display labels, not enforced semantics.
Cardinality. The quoted strings on either side of an arrow — `"1"`, `"*"`, `"0..1"` — say how many instances participate. Most people skip them. They are usually the most informative characters on the line.
Comments. A line starting with `%%` is ignored. It must be on its own line; a trailing `%%` after a declaration is a syntax error.
What are the eight relationship types?
| Syntax | Relationship | Read as | Use when | |---|---|---|---| | `<\|--` | Inheritance | B is a kind of A | A subclass extends a base class | | `*--` | Composition | A owns B; B dies with A | An order line cannot exist without its order | | `o--` | Aggregation | A holds B; B survives alone | A team holds members who exist independently | | `-->` | Association | A refers to B | A customer places orders | | `--` | Link | A and B are connected | Direction genuinely does not matter | | `..>` | Dependency | A uses B transiently | A method takes B as a parameter | | `..\|>` | Realization | A implements interface B | A concrete class satisfies a contract | | `..` | Dashed link | A and B are loosely connected | A weak or conceptual pairing |
The closed arrowhead always points at the parent or the interface, which is the detail people reverse most often. `Dog <|-- Animal` says animals are a kind of dog. Write `Animal <|-- Dog`.
Composition or aggregation: how do I choose?
Ask one question: if the whole is deleted, does the part still make sense?
An order line without its order is meaningless — it is not a line of anything. That is composition, `*--`. An employee without their team still exists, still has a name and a payroll record, and will probably join another team. That is aggregation, `o--`.
The test is about lifecycle, not about how the code stores the reference. A field holding a list of objects can be either one; the diagram is asserting something the code cannot tell you, which is exactly why the diagram is worth drawing.
When you genuinely do not know, use plain association `-->`. A wrong composition arrow is a confident false claim about the domain. A plain association is honest.
What makes a class diagram unreadable?
Three habits, all of them well intentioned.
Every class, because the diagram should be complete. A diagram with forty classes is a diagram nobody reads. It is not documentation, it is a picture of a package listing. Pick the eight to twelve classes that carry the behaviour you are explaining and leave the rest out. Completeness is what the source code is for.
Every member, because the fields are the interesting part. They are not. A reader scanning a class box wants to know what the class is responsible for, which is usually two or three methods and one or two defining fields. A box with nineteen getters buries that.
No cardinality, because it clutters. Cardinality is the difference between "a customer has orders" and "a customer has zero or more orders, each belonging to exactly one customer." The second sentence answers a design question. It costs four characters.
A useful class diagram is a selective argument about a system, not a rendering of it. The same discipline applies to every diagram type, and the failure mode is identical to the one described in our Mermaid sequence diagram guide, where too many participants destroys a diagram that is otherwise correct.
How do I show a class diagram to people who do not read code?
With difficulty, if it stays static.
A class diagram is a graph of simultaneous relationships. That is fine on a screen the reader controls, where they trace one arrow at a time at their own pace. On a slide in front of a room, all of it lands at once, and the audience is doing graph traversal while you talk. They will not follow, and the usual response — shrinking the font to fit more in — makes it worse.
There is a structural reason this hurts more for class diagrams than for a flowchart. A flowchart has a direction, so the eye at least knows where to start. A class diagram often has no entry point at all, so every viewer starts somewhere different and reconstructs a different story.
The fix is to give the diagram an order it does not have on its own: introduce the core entity, then the things it owns, then the interfaces it depends on, one relationship at a time. That is what an animated version does. FluxDiagram takes a Mermaid class diagram definition and produces an animated build of it, exported as GIF, MP4, or WebM and embedded into PowerPoint, Google Slides, or Keynote like any other media file. The definition stays in the repository where it belongs; the animation is how it survives a meeting. The general case is covered in converting a Mermaid diagram into an animation.
Frequently asked questions
Can Mermaid generate a class diagram from my source code? No. Mermaid renders a definition you write; it does not parse a codebase. Several separate tools emit Mermaid syntax from source, and their output is a starting point that still needs trimming, because a generated diagram includes everything and a useful one does not.
Does Mermaid support generics and namespaces? Yes to both. Generic types use tildes, as in `List~Order~`, because angle brackets conflict with the arrow syntax. Namespaces group classes with a `namespace Name { }` block. Check your renderer's version before relying on either, since GitHub pins an older Mermaid release than the current one.
How do I add a note to a class? Use `note for ClassName "text"` on its own line, or a standalone `note "text"`. Notes are for context the arrows cannot carry, such as a constraint or an open question. They are not a place to restate what the diagram already shows.
FluxDiagram generates animated diagrams you embed into the deck you already have, in PowerPoint, Google Slides or Keynote. Paste a class diagram definition into the Mermaid converter to see the animated version.