PlantUML Class Diagram Generator Online
A class diagram describes structure: what types exist, what they hold, and how they relate. It is the diagram that answers "how is this domain modelled?" without making anyone read the whole codebase.
The editor below opens with a small domain model you can edit directly. The preview updates as you type, and everything renders locally in your browser.
A small order-management model. Edit the classes and relationships to match your own domain.
Getting the relationship arrows right
Most of the meaning in a class diagram lives in the connectors, and they are easy to mix up. <|-- is inheritance, with the hollow triangle pointing at the parent. <|.. is interface implementation - same triangle, dashed line. *-- is composition: the whole owns the part, and the part dies with it. o-- is aggregation: a looser has-a, where the part outlives the whole.
If you only remember one distinction, make it composition versus aggregation. An OrderLine inside an Order is composition - delete the order and the lines are meaningless. A Customer in a Team is aggregation - the customer exists either way.
Note the direction. Animal <|-- Dog and Dog --|> Animal draw the same thing; the arrowhead always sits at the parent end. Writing it backwards is a common way to end up with an inheritance tree pointing the wrong way.
Fields, methods and visibility
Members go inside braces after the class name. A leading +, -, # or ~ sets visibility to public, private, protected or package-private, and PlantUML renders each as a small icon. If you find the icons noisy, skinparam classAttributeIconSize 0 (already in the starter) switches them back to plain symbols.
PlantUML decides whether a member is a field or a method by looking for parentheses. +login() becomes a method, +email becomes a field. You can force either with the {field} and {method} modifiers when the guess is wrong.
{static} and {abstract} mark members as static or abstract, rendering them underlined and italic respectively.
Multiplicity and labels
Multiplicity goes in quotes on either end of the connector: Customer "1" --> "0..*" Order. This is where a class diagram earns its keep, because "a customer has orders" is ambiguous and 1 to 0..* is not.
Add a label after a colon to name the relationship - : places - and PlantUML will draw it on the line. Keep labels to a verb or short phrase; anything longer belongs in the surrounding document.
When the layout fights you
You describe relationships, not positions. The layout engine decides placement, which is usually fine and occasionally infuriating. left to right direction switches the overall flow and often fixes a diagram that has grown too tall.
For finer control, together { ... } keeps a group of classes near each other, and a hidden edge such as A -[hidden]- B nudges the ranking without drawing anything. Reach for these only after the diagram is otherwise correct - it is easy to spend more time on layout than on the model.
Class diagram syntax reference
| Syntax | What it does |
|---|---|
class Name { } | A class, with members between the braces |
abstract class Name | An abstract class, rendered in italics |
interface Name | An interface |
enum Name | An enumeration - list the constants inside |
A <|-- B | B inherits from A (hollow triangle at A) |
A <|.. B | B implements interface A (dashed) |
A *-- B | Composition - A owns B, B dies with A |
A o-- B | Aggregation - A has B, B survives independently |
A --> B | Directed association |
A -- B | Plain association |
A ..> B | Dependency - A uses B |
A "1" -- "0..*" B | Multiplicity on each end |
A -- B : label | Name the relationship |
+ - # ~ | Public, private, protected, package-private |
{static} / {abstract} | Modifiers on a member |
{field} / {method} | Force how a member is classified |
package Name { } | Group classes into a package box |
note left of A : text | Attach a note to a class |
left to right direction | Flip the layout when the diagram gets tall |
hide empty members | Hide the empty compartments on bare classes |
Examples
Interfaces and implementations
The shape you want when documenting a strategy or plugin point.
Input
@startuml
interface PaymentMethod {
+charge(amount: Money): Receipt
+refund(r: Receipt): void
}
class CardPayment implements PaymentMethod
class BankTransfer implements PaymentMethod
class StoreCredit implements PaymentMethod
class Checkout {
-method: PaymentMethod
+complete(): Receipt
}
Checkout ..> PaymentMethod : uses
@endumlPackages and cross-package dependencies
Useful for showing layering, and for showing where that layering has been violated.
Input
@startuml
left to right direction
package "web" {
class OrderController
}
package "domain" {
class Order
class OrderService
}
package "infra" {
class OrderRepository
}
OrderController ..> OrderService
OrderService ..> Order
OrderService ..> OrderRepository
OrderRepository ..> Order
@endumlHow to use this class diagrams editor
- 1
List the types first
Write a bare
class Nameline for each type in the model and render it. Getting the vocabulary down before the relationships keeps the diagram honest. - 2
Connect them
Add relationships using
<|--for inheritance,*--for composition and-->for association. Check each arrowhead is at the end you meant. - 3
Add detail where it helps
Fill in fields and methods only for the classes the reader needs them for, and add multiplicity where the cardinality is not obvious.
- 4
Export or commit it
Download SVG for documentation, PNG for a slide, or the .puml source so the diagram lives in version control next to the code it describes.
Frequently asked questions
How do I show inheritance in a PlantUML class diagram?
Use Parent <|-- Child, or equivalently Child --|> Parent. The hollow triangle always sits at the parent end. PlantUML also accepts the keyword form class Child extends Parent, which some people find easier to read.
What is the difference between *-- and o-- ?
*-- is composition and o-- is aggregation. Composition means the part belongs to the whole and does not outlive it - order lines inside an order. Aggregation is a looser has-a, where the part exists independently - a customer in a team.
How do I set multiplicity like one-to-many?
Put the multiplicity in quotes at each end of the connector: Customer "1" --> "0..*" Order. Any label works, so "1", "0..1", "1..*" and "*" are all fine.
Can I control where classes are placed?
Only indirectly. PlantUML delegates positioning to a layout engine. left to right direction changes the overall flow, together { } keeps classes near each other, and hidden edges like A -[hidden]- B influence ranking. There is no way to set exact coordinates, which is the trade-off for never having to align anything by hand.
How do I hide the empty boxes under a class name?
Add hide empty members. Classes you have declared without fields or methods will then render as a single box instead of showing empty compartments.