How to Create Class Diagrams in Confluence (Mermaid Examples)
Class diagrams are the standard way to model object-oriented systems. They show the classes in your codebase, their attributes and methods, and the relationships between them -- inheritance hierarchies, composition, aggregation, and simple associations. Whether you are documenting a domain model, onboarding new engineers onto a codebase, or collaborating on a design before writing a single line of code, a UML class diagram communicates structure faster than paragraphs of prose.
If your team uses Confluence for technical documentation, embedding class diagrams directly on your pages keeps your design docs next to your architecture decisions, runbooks, and sprint planning notes. With Mermaid Plus for Confluence, you can write class diagrams in plain text and render them instantly, no external drawing tool required.
Why Create Class Diagrams in Confluence?
Teams that embed diagrams inside Confluence instead of linking to external tools get several concrete benefits:
Diagrams evolve with documentation. When your class diagram lives on the same page as the architecture decision record that explains why PaymentService depends on PaymentGateway instead of calling the gateway directly, both stay synchronized. Edit the diagram, publish the page, and everyone sees the latest version.
No stale images. Exporting a PNG from a desktop diagramming tool and attaching it to a Confluence page guarantees that the image goes out of date the next time someone refactors a class. A Mermaid macro always renders the current code.
Text-based and version-friendly. Mermaid class diagrams are plain text, which means they work with Confluence page history, diffs, and search. You can find every page that mentions OrderRepository by searching Confluence -- even if the term only appears inside a Mermaid macro.
Fast to create and iterate. Typing class User { +String name } is faster than dragging boxes, aligning arrows, and resizing shapes in a visual editor. When you want to add a field or a method, you type it. When you want to change a relationship, you change one operator character.
Step-by-Step Tutorial: Create Your First Class Diagram
Follow these five steps to go from a blank Confluence page to a fully rendered UML class diagram.
Step 1 -- Install Mermaid Plus for Confluence
Head to the Atlassian Marketplace and search for Mermaid Plus for Confluence. Click Get App and follow the installation prompts. The app supports both Confluence Cloud and Confluence Data Center. If your organization requires admin approval for marketplace apps, send the link to your Confluence administrator.
Once installed, the Mermaid Plus macro becomes available on every space in your Confluence instance. No per-space configuration required.
Step 2 -- Insert the Mermaid Macro on a Confluence Page
Open any Confluence page in edit mode. Type /mermaid in the editor and select Mermaid Plus for Confluence from the dropdown. The configuration panel opens with a three-column layout:
- Left column: Live Preview, which renders your diagram in real time as you type
- Middle column: Quick Templates for all 26 supported diagram types
- Right column: Settings (font, colors, theme, output size) and the Code Editor
Step 3 -- Write the classDiagram Header and Define Classes
Start your class diagram with the classDiagram keyword. Then define classes using the class keyword followed by the class name and a block of attributes and methods in curly braces:
classDiagram
class Animal {
+String name
+int age
+makeSound()
}
The + symbol before name and age means public visibility. You will learn more about visibility modifiers later in this guide.
Step 4 -- Add Relationships Between Classes
Mermaid supports the full set of UML class relationship operators. To connect two classes, use an arrow operator between them:
classDiagram
class Animal {
+String name
+makeSound()
}
class Dog {
+String breed
+fetch()
}
Animal <|-- Dog : inherits
The <|-- operator creates an inheritance (generalization) arrow pointing from the subclass to the superclass. You will find a complete reference table for all relationship operators in the next section.
Step 5 -- Save and Publish the Diagram
Check the live preview in the left column to verify the diagram renders correctly. Adjust the theme, colors, or output size in the right column if needed. When you are satisfied, click Save to insert the macro into the page, then Publish the Confluence page.
To edit the diagram later, click on the rendered diagram in view mode and select Edit. All your code and settings are preserved.
Mermaid Class Diagram Syntax Reference
Before diving into the full examples, here is a quick-reference for the syntax elements you will use most often.
Relationship Operators
Relationships are the core of any class diagram. Mermaid supports all standard UML relationships:
| Relationship | Syntax | Meaning |
|---|---|---|
| Inheritance | `Parent < | -- Child` |
| Composition | Whole *-- Part | Part cannot exist without Whole (strong ownership) |
| Aggregation | Whole o-- Part | Part can exist independently (weak ownership) |
| Association | A --> B | A knows about B (navigable association) |
| Bidirectional | A -- B | A and B know about each other |
| Dependency | A ..> B | A depends on B (uses temporarily) |
| Realization | `Interface .. | > Class` |
You can add labels to any relationship by appending a colon and text:
Animal <|-- Dog : extends
Order *-- LineItem : contains
Visibility Modifiers
Visibility modifiers indicate the access level of class members:
| Symbol | Visibility | Description |
|---|---|---|
+ | Public | Accessible from any class |
- | Private | Accessible only within the class |
# | Protected | Accessible within the class and its subclasses |
~ | Package/Internal | Accessible within the same package or module |
Example:
classDiagram
class User {
+String email
-String passwordHash
#int failedLoginAttempts
+login(password) bool
-hashPassword(password) String
#incrementFailedAttempts()
}
Return Types and Parameter Types
Methods can specify parameter types and return types using several formats:
classDiagram
class UserRepository {
+findById(id: int) User
+findAll() List~User~
+save(user: User) void
+deleteById(id: int) bool
}
Generics
Mermaid supports generic types using the tilde ~ notation. This is useful for collections, repositories, and other parameterized types:
classDiagram
class List~T~ {
+add(item: T) void
+get(index: int) T
+size() int
}
class Map~K, V~ {
+put(key: K, value: V) void
+get(key: K) V
+containsKey(key: K) bool
}
When you use generics in relationship definitions, wrap the generic type in quotes to avoid parse errors:
List~User~ "List<User>"
Annotations and Stereotypes
Mermaid supports class annotations (stereotypes) using the << >> notation. This is commonly used to mark classes as interfaces, abstract classes, services, or enums:
classDiagram
class Shape {
<<abstract>>
+draw() void
+area() double
}
class Drawable {
<<interface>>
+render(canvas: Canvas) void
}
class Color {
<<enumeration>>
RED
GREEN
BLUE
}
You can also use the shorthand notation inline:
class Shape {
<<abstract>>
}
Namespaces and Packages
When your class diagram grows beyond a handful of classes, namespaces help you organize related classes into logical groups. Mermaid namespaces draw a border around a group of classes and prefix their names:
classDiagram
namespace PaymentDomain {
class Payment {
+BigDecimal amount
+Currency currency
+process()
}
class PaymentGateway {
<<interface>>
+charge(payment: Payment) Result
+refund(payment: Payment) Result
}
}
namespace UserDomain {
class Account {
+String accountId
+getBalance() BigDecimal
}
}
Account --> Payment : initiates
Namespaces are especially useful when you are modeling a domain-driven design with bounded contexts, or when you want to show how classes from different modules or packages relate to each other.
Class Members Without Body
For quick diagrams where you only need to show relationships, you can define class members inline without using a body block:
classDiagram
Animal : +String name
Animal : +makeSound()
Dog : +String breed
Animal <|-- Dog
This is equivalent to defining the class with a body block, but it keeps the code more compact for simple diagrams.
3 Copy-Paste Class Diagram Examples
Below are three practical examples you can paste directly into the Mermaid Plus macro in Confluence. Each example demonstrates progressively more advanced Mermaid class diagram features.
Example 1 -- Basic Class Diagram: Vehicle Hierarchy
This example shows a simple inheritance hierarchy with abstract classes and concrete implementations. It is a good starting point for documenting any class hierarchy in your codebase.
classDiagram
class Vehicle {
<<abstract>>
+String make
+String model
+int year
+startEngine()
+stopEngine()
+getInfo() String
}
class Car {
+int numDoors
+String trunkSize
+openTrunk()
+closeTrunk()
}
class Motorcycle {
+String handlebarType
+bool hasSidecar
+popWheelie()
}
class Truck {
+double payloadCapacity
+int numAxles
+loadCargo(weight: double)
+unloadCargo()
}
class Engine {
-int horsepower
-String fuelType
+ignite()
+shutdown()
}
Vehicle <|-- Car : extends
Vehicle <|-- Motorcycle : extends
Vehicle <|-- Truck : extends
Vehicle *-- Engine : has
This diagram covers three key concepts:
- Abstract classes --
Vehicleis marked with<<abstract>>and defines the common interface for all vehicle types - Inheritance --
Car,Motorcycle, andTruckall extendVehicleusing the<|--operator - Composition --
Vehiclehas a composedEngineusing the*--operator, meaning the engine cannot exist without the vehicle
Example 2 -- Observer Design Pattern
Design patterns are one of the most common reasons teams create class diagrams. The Observer pattern is used everywhere: event systems, message queues, UI frameworks, and reactive programming. This diagram shows the full pattern with interfaces, concrete implementations, and the relationship between subject and observers.
classDiagram
class Subject {
<<interface>>
+attach(observer: Observer) void
+detach(observer: Observer) void
+notifyObservers() void
}
class Observer {
<<interface>>
+update(data: any) void
}
class ConcreteSubject {
-List~Observer~ observers
-any state
+attach(observer: Observer) void
+detach(observer: Observer) void
+notifyObservers() void
+getState() any
+setState(newState: any) void
}
class ConcreteObserverA {
-any observedState
+update(data: any) void
+display() void
}
class ConcreteObserverB {
-any observedState
+update(data: any) void
+log() void
}
class EventManager {
-Map~String, List~Observer~~ listeners
+subscribe(eventType: String, observer: Observer) void
+unsubscribe(eventType: String, observer: Observer) void
+notify(eventType: String, data: any) void
}
Subject <|.. ConcreteSubject : implements
Observer <|.. ConcreteObserverA : implements
Observer <|.. ConcreteObserverB : implements
ConcreteSubject --> Observer : notifies
EventManager --> Observer : manages
Subject <|-- EventManager : extends
This diagram introduces several advanced features:
- Interface realization --
ConcreteSubjectimplementsSubjectusing the..<|operator (dashed line with open triangle) - Generic collections --
List~Observer~andMap~String, List~Observer~~show nested generics - Dependencies and associations --
ConcreteSubject --> Observershows a navigable association (the subject holds references to observers) - Multiple relationship types -- Inheritance, realization, and association all appear in the same diagram
Use this diagram as a template when documenting any event-driven or publish-subscribe architecture in your system.
Example 3 -- Real-World Domain Model: E-Commerce System
This example models a realistic e-commerce domain with customers, orders, products, payments, and shipping. It demonstrates how to use namespaces, composition, aggregation, and cardinality labels in a single, comprehensive diagram. This is the kind of diagram you would include in a technical design document or architecture decision record.
classDiagram
namespace Customers {
class Customer {
+String customerId
+String email
+String firstName
+String lastName
+placeOrder(items: List~Product~) Order
+getOrderHistory() List~Order~
+updateProfile(data: Map~String, String~) void
}
class Address {
+String street
+String city
+String state
+String zipCode
+String country
+getFullAddress() String
}
class LoyaltyAccount {
+int points
+String tier
+earnPoints(amount: double) void
+redeemPoints(points: int) void
}
}
namespace Orders {
class Order {
+String orderId
+Date createdAt
+String status
+BigDecimal totalAmount
+addItem(item: LineItem) void
+removeItem(itemId: String) void
+calculateTotal() BigDecimal
+cancel() void
}
class LineItem {
+String lineItemId
+int quantity
+BigDecimal unitPrice
+getSubtotal() BigDecimal
}
class OrderStatus {
<<enumeration>>
PENDING
CONFIRMED
PROCESSING
SHIPPED
DELIVERED
CANCELLED
}
}
namespace Products {
class Product {
+String productId
+String name
+String description
+BigDecimal price
+int stockQuantity
+isInStock() bool
+reduceStock(qty: int) void
}
class Category {
+String categoryId
+String name
+String description
+getProducts() List~Product~
}
class ProductVariant {
+String variantId
+String color
+String size
+BigDecimal priceAdjustment
}
}
namespace Payments {
class Payment {
+String paymentId
+BigDecimal amount
+String method
+String status
+process() bool
+refund() bool
}
class PaymentGateway {
<<interface>>
+charge(payment: Payment) Result
+refund(paymentId: String) Result
+verify(paymentId: String) Result
}
class StripeGateway {
-String apiKey
+charge(payment: Payment) Result
+refund(paymentId: String) Result
+verify(paymentId: String) Result
}
class PayPalGateway {
-String clientId
-String clientSecret
+charge(payment: Payment) Result
+refund(paymentId: String) Result
+verify(paymentId: String) Result
}
}
namespace Shipping {
class Shipment {
+String trackingNumber
+String carrier
+Date estimatedDelivery
+String status
+track() ShipmentStatus
}
}
Customer "1" --> "*" Order : places
Customer "1" --> "*" Address : has
Customer "1" o-- "0..1" LoyaltyAccount : optionally has
Order "1" *-- "*" LineItem : contains
Order "1" --> "0..1" Payment : paid by
Order "1" --> "0..1" Shipment : shipped via
Order --> OrderStatus : has status
LineItem "*" --> "1" Product : references
Product "*" o-- "*" Category : categorized in
Product "1" o-- "*" ProductVariant : has variants
PaymentGateway <|.. StripeGateway : implements
PaymentGateway <|.. PayPalGateway : implements
Payment ..> PaymentGateway : processed through
This diagram demonstrates every major Mermaid class diagram feature:
- Namespaces -- Five namespaces (
Customers,Orders,Products,Payments,Shipping) group related classes into bounded contexts - Cardinality labels --
"1","*","0..1","1..*"labels on relationship lines show multiplicity - Composition vs aggregation --
Order *-- LineItem(composition, items cannot exist without the order) vsCustomer o-- LoyaltyAccount(aggregation, account exists independently) - Enumeration classes --
OrderStatusis marked with<<enumeration>>and lists its values - Interface realization --
StripeGatewayandPayPalGatewayimplementPaymentGateway - Dependencies --
Payment ..> PaymentGatewayshows a transient dependency - Generics --
List~Product~,Map~String, String~, and other parameterized types throughout
This is the level of detail you would use for a technical design document, a system architecture page, or an onboarding guide for new engineers joining the team.
Tips for Building Effective Class Diagrams
Start Simple, Then Add Detail
Begin with class names and relationships only. Get the structure right first, then fill in attributes and methods. This two-pass approach prevents you from getting bogged down in details before the overall shape of the diagram is correct.
Use Namespaces to Manage Complexity
Any diagram with more than six or seven classes benefits from namespaces. Group classes by module, package, or bounded context. This makes the diagram easier to read and mirrors how your code is actually organized.
Be Consistent with Visibility
Pick a convention and stick to it. If you show public members with + in one class, show them in every class. Mixing conventions within a single diagram creates confusion about what is and is not accessible.
Label Relationships
Add labels to your relationship arrows, especially when the relationship is not immediately obvious from the class names alone. Order "1" *-- "*" LineItem : contains is clearer than Order *-- LineItem.
Choose Composition Over Aggregation Deliberately
Composition (*--) means the child cannot exist without the parent. Aggregation (o--) means it can. This distinction matters in your code: if deleting an Order should also delete its LineItem records, use composition. If deleting a Customer should not delete their Address (because the address might be shared), use aggregation.
Keep Diagrams Focused
A single class diagram does not need to show every class in your system. Focus on one subsystem or one bounded context per diagram. If you find yourself adding a fourth or fifth namespace, consider splitting the diagram into two pages and linking between them.
Use Themes for Visual Consistency
Mermaid Plus for Confluence offers four built-in themes: Default, Dark, Forest, and Neutral. Pick one theme for all class diagrams in a space and stick with it. Consistent visual style across pages makes your documentation feel polished and professional. The Default theme lets you customize node, text, border, line, and background colors to match your company brand.
For detailed configuration options including font families, color pickers, and output sizes, refer to the Mermaid Plus for Confluence usage guide.
Common Mistakes and How to Fix Them
Missing class keyword. Every class definition must start with class. Writing User { +String name } without the class keyword produces a parse error. The correct form is class User { +String name }.
Wrong arrow direction. Inheritance arrows point from child to parent: Parent <|-- Child, not Child --> Parent. The open triangle always points at the superclass or interface. If your inheritance arrows look reversed, swap the sides of the operator.
Unquoted generics in relationships. When using generic types in relationship lines, wrap the full type in quotes: "List~User~". Without quotes, Mermaid may misparse the tilde characters.
Omitting return types. While return types are optional in Mermaid, including them makes the diagram more useful as documentation. +findById(id: int) User is more informative than +findById(id).
Overcrowding. A class diagram with 15 classes and 30 relationships becomes unreadable. If your diagram has grown too large, split it by namespace, module, or feature area. Two focused diagrams are always better than one overwhelming diagram.
Forgetting to close body blocks. Every { must have a matching }. If your diagram fails to render, check that every class body is properly closed. The live preview in Mermaid Plus will show you parse errors in real time, which makes this easy to catch.
When to Use Class Diagrams vs Other Diagram Types
Class diagrams are not the right tool for every situation. Here is a quick guide to help you choose:
- Class diagram -- Use when documenting static structure: class hierarchies, domain models, database entity relationships, and API contracts
- Sequence diagram -- Use when documenting dynamic behavior: message flows between services, API request/response chains, and authentication flows. See how to create sequence diagrams in Confluence
- Flowchart -- Use when documenting processes: decision trees, approval workflows, and algorithmic logic. See how to create flowcharts in Confluence
- ER diagram -- Use when documenting database schemas directly, without the object-oriented baggage of methods and visibility modifiers
Many technical design documents benefit from combining multiple diagram types on the same Confluence page. A class diagram shows the structure, a sequence diagram shows how the classes interact at runtime, and a flowchart shows the business process that triggers the whole flow.
Related Resources
- Mermaid Plus for Confluence usage guide -- configuration panel walkthrough, theme settings, font and color customization, and all 26 supported diagram types
- How to create sequence diagrams in Confluence -- document message flows between services with copy-paste Mermaid examples
- Mermaid syntax cheat sheet for Confluence -- quick reference for flowcharts, sequence diagrams, ER diagrams, and more
- How to create flowcharts in Confluence -- process diagrams, decision trees, and workflow documentation with Mermaid
Class diagrams are one of the most valuable tools in a software team's documentation arsenal. They capture the static structure of your system in a way that prose alone cannot. With Mermaid Plus for Confluence, creating and maintaining class diagrams is as simple as writing text. Install the app, paste one of the examples above into a Confluence page, and start documenting your system's architecture where it belongs -- alongside everything else your team needs.