Answer: Write Mermaid classDiagram code on the left and a UML class diagram renders on the right about 400 ms after you stop typing. Export SVG for docs or a 2Γ PNG for slides. It runs in your browser with no signup, but it doesn't save, so copy your code before you close the tab.
Type Mermaid syntax, get a UML class diagram β live
class Vehicle { +String name +start() void } and connect with Vehicle <|-- Car for inheritance, *-- for composition, o-- for aggregation. Visibility markers (+ public, - private, # protected) prefix each member. This maker renders the MIT-licensed Mermaid 11 library in your browser and exports clean SVG or PNG.
| Syntax | What it draws |
|---|---|
classDiagram | Required first line |
class Order { ... } | Box with member compartments |
+String email | Public attribute (member syntax: visibility, name, optional type) |
-hashPassword(pwd) | Private method |
#rowCount() int | Protected method with return type |
<<interface>> | Stereotype label line inside the class body |
<<abstract>> / <<enumeration>> | Other common stereotypes |
A <|-- B | Inheritance β B extends A (triangle at A) |
A <|.. B | Realization β B implements interface A |
Whole *-- Part | Composition β part dies with whole |
Whole o-- Part | Aggregation β part can outlive whole |
A -- B / A --> B | Association / directed association |
A ..> B : uses | Dependency β A temporarily uses B |
A "1" --> "0..*" B | Multiplicity labels on the ends |
note for Order "text" | A note attached to one class |
The direction you write a relationship matters: in Vehicle <|-- Car the triangle points at Vehicle, the parent. Mermaid is picky about spaces inside braces β one member per line, no blank lines inside the block.
Most mistakes in class diagrams are the wrong arrow, not the wrong syntax. Ask the question in the second column, and if the answer is yes, that's your arrow.
| Relationship | Ask yourself | Mermaid | In code it usually looks like |
|---|---|---|---|
| Inheritance | Is B a kind of A? | A <|-- B | class B extends A |
| Realization | Does B promise A's methods without inheriting code? | A <|.. B | class B implements A |
| Composition | Does Part die when Whole is deleted? | Whole *-- Part | Whole creates Part in its constructor and never shares it |
| Aggregation | Does Whole hold Parts that live on without it? | Whole o-- Part | A list of objects passed in from outside |
| Association | Does A keep a long-lived reference to B? | A --> B | A field of type B |
| Dependency | Does A only use B briefly? | A ..> B | B as a method parameter or local variable |
When composition and aggregation both seem right, pick association. It's never wrong, just less specific, and reviewers argue far less about a plain arrow than a diamond.
| Write | Means | Example |
|---|---|---|
+ - # ~ | Public, private, protected, package/internal | ~int retryCount |
* after a method | Abstract method, shown in italics | +area() double* |
$ after a member | Static, shown underlined | +create() Order$ |
~Type~ | Generic type, drawn with angle brackets | class Box~T~ or +List~String~ tags |
direction LR | Lay the diagram out left to right (TB is the default) | Second line of the default diagram |
"1" --> "0..*" | Multiplicity. Common values: 1, 0..1, 1..*, *, n, 0..n, 1..n | Customer "1" --> "0..*" Order |
Generics use tildes because angle brackets clash with Mermaid's own syntax. Nested generics like List~List~int~~ work, but a generic with a comma inside, such as Map~K, V~, isn't supported yet according to the Mermaid docs.
The two download buttons give you different files, and it's worth knowing which to use before you paste one into a document.
| SVG | PNG | |
|---|---|---|
| File name | class-diagram.svg | class-diagram.png |
| Resolution | Vector, sharp at any zoom | 2Γ the on-screen diagram size |
| Background | None of its own | Solid dark (#0f1117), matching the preview |
| Best for | Wikis, READMEs, design docs with a dark theme | Slides, chat messages, tickets |
| Watch out for | Light text from the dark theme can fade on a white page | Text can't be edited afterwards |
The editor doesn't save anything between visits. Reload the page and it goes back to the payment example. That's deliberate, since your code never leaves the browser, but it means the Copy code button is the real save button. Paste the code into your repo next to the classes it describes, and the diagram can be re-rendered whenever the design changes. That's the point of diagrams as code: the source is a few lines of text that diff cleanly in a pull request, unlike a binary image.
The renderer itself, Mermaid 11, loads from a public CDN the first time you open the page. If that request is blocked on a locked-down network, the status line says so. The same syntax works in GitHub and GitLab Markdown inside a ```mermaid code block, so a diagram you build here can live directly in a README. For data models, the ER diagram maker is the better fit, and the Mermaid diagram suite covers every other diagram type.
Class diagrams are the static view of an object-oriented design: what types exist, what they hold, what they can do, and how they relate. They don't show control flow (that's a sequence diagram) or stored data (that's an ER diagram). They're the diagram you sketch before writing the first class, and the one you keep beside the code as it grows.
The editor on the left renders about 400 ms after you stop typing; the status line flags parse errors. Export SVG for documentation or PNG for a slide. Both are produced locally β your code never leaves the browser.
The default diagram models a payment flow. Count before you draw: 6 classes, 5 relationships. PaymentMethod is an interface (the <<interface>> stereotype); CreditCard and BankAccount each realize it with <|.., so two dotted lines with hollow triangles point at that box. A third dotted line arrives there too: Order ..> PaymentMethod : pays with is a dependency, drawn with an open arrowhead instead of a triangle. Same line style, different meaning, and the arrowhead is how you tell them apart. Order *-- LineItem is composition β delete the order and its line items go with it. Customer "1" --> "0..*" Order says one customer can hold any number of orders, including none.
classDiagram β the type declarationPaymentMethod <|.. CreditCard β realizesOrder *-- LineItem β compositionCustomer "1" --> "0..*" Order : places β association with multiplicity and a labelSix classes and five relationships fit on one screen; the same drawing in a canvas tool is twenty drag operations and an alignment pass. That's the usual experience with diagrams-as-code β structure is cheap to revise, so you revise it more often.
Open a file with classDiagram, declare classes with class Name { ... }, list attributes and methods inside the braces (visibility marker first: + public, - private, # protected), then connect classes with relationship arrows like Vehicle <|-- Car for inheritance. This maker renders live in your browser and exports SVG β no account, no watermark.
They are UML visibility markers. + means public (any class can call it), - means private (only the class itself), and # means protected (the class and its subclasses). ~ marks package-private. You write them at the start of each member line, as in +String name or -balance() float, and Mermaid shows them as a gutter character next to each member.
Inheritance is ClassA <|-- ClassB (a hollow triangle pointing at the parent). Composition, where the part dies with the whole, is Whole *-- Part. Aggregation, where parts survive, is Whole o-- Part. Plain association is --, dependency (uses-temporarily) is ..>, and realization of an interface is <|.. Implementer. The shape at the parent end and the line style carry the meaning.
Put the multiplicity on the relationship line with quotes: Customer "1" --> "*" Order : places. Read it as one customer places zero-or-more orders. Common values are 1, 0..1, *, and 1..*, and you can put a label after a colon to name the relationship in plain English.
Yes. Inside the class body, write <<abstract>> or <<interface>> on its own line and Mermaid adds the UML stereotype label. <<enumeration>> works the same way for enums, where you then list the allowed values as members. The stereotype appears as a label above the class name. To mark a single method as abstract, end it with an asterisk, as in draw()*, and Mermaid sets it in italics, following the UML convention.
No. Nothing is stored in your browser or sent to a server, so reloading the page brings back the example diagram. Click Copy code and keep the Mermaid source somewhere, ideally in the same repository as the code it describes, then paste it back in to edit later.
Wrap the type in tildes instead of angle brackets: List~String~. It works on class names too, as in class Box~T~, and Mermaid draws it with angle brackets. Nested generics are supported, but a generic with a comma, such as Map~K, V~, isn't yet.
The PNG export paints the same dark background as the preview, then draws the diagram at twice its on-screen size, so it stays readable on slides. If you need a diagram for a light document, use the SVG, which has no background of its own, and check the text contrast after pasting.