# Create UML Class Diagrams in Confluence — Free with Mermaid

May 2, 2026 ·

<!-- -->

16 min read

[NGPilot](https://ngpilot.com)

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?[​](#why-create-class-diagrams-in-confluence "Direct link to 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[​](#step-by-step-tutorial-create-your-first-class-diagram "Direct link to 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[​](#step-1----install-mermaid-plus-for-confluence "Direct link to Step 1 -- Install Mermaid Plus for Confluence")

Head to the [Atlassian Marketplace](https://marketplace.atlassian.com/) 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[​](#step-2----insert-the-mermaid-macro-on-a-confluence-page "Direct link to 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 29 supported diagram types
* **Right column**: Settings (font, colors, theme, output size) and the Code Editor

### Step 3 -- Write the `classDiagram` Header and Define Classes[​](#step-3----write-the-classdiagram-header-and-define-classes "Direct link to 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[​](#step-4----add-relationships-between-classes "Direct link to 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[​](#step-5----save-and-publish-the-diagram "Direct link to 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[​](#mermaid-class-diagram-syntax-reference "Direct link to 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[​](#relationship-operators "Direct link to 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 ..&gt; 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 "Direct link to 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[​](#return-types-and-parameter-types "Direct link to 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[​](#generics "Direct link to 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[​](#annotations-and-stereotypes "Direct link to 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[​](#namespaces-and-packages "Direct link to 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[​](#class-members-without-body "Direct link to 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[​](#3-copy-paste-class-diagram-examples "Direct link to 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[​](#example-1----basic-class-diagram-vehicle-hierarchy "Direct link to 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:

1. **Abstract classes** -- `Vehicle` is marked with `<<abstract>>` and defines the common interface for all vehicle types
2. **Inheritance** -- `Car`, `Motorcycle`, and `Truck` all extend `Vehicle` using the `<|--` operator
3. **Composition** -- `Vehicle` has a composed `Engine` using the `*--` operator, meaning the engine cannot exist without the vehicle

### Example 2 -- Observer Design Pattern[​](#example-2----observer-design-pattern "Direct link to 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:

1. **Interface realization** -- `ConcreteSubject` implements `Subject` using the `..<|` operator (dashed line with open triangle)
2. **Generic collections** -- `List~Observer~` and `Map~String, List~Observer~~` show nested generics
3. **Dependencies and associations** -- `ConcreteSubject --> Observer` shows a navigable association (the subject holds references to observers)
4. **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[​](#example-3----real-world-domain-model-e-commerce-system "Direct link to 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:

1. **Namespaces** -- Five namespaces (`Customers`, `Orders`, `Products`, `Payments`, `Shipping`) group related classes into bounded contexts
2. **Cardinality labels** -- `"1"`, `"*"`, `"0..1"`, `"1..*"` labels on relationship lines show multiplicity
3. **Composition vs aggregation** -- `Order *-- LineItem` (composition, items cannot exist without the order) vs `Customer o-- LoyaltyAccount` (aggregation, account exists independently)
4. **Enumeration classes** -- `OrderStatus` is marked with `<<enumeration>>` and lists its values
5. **Interface realization** -- `StripeGateway` and `PayPalGateway` implement `PaymentGateway`
6. **Dependencies** -- `Payment ..> PaymentGateway` shows a transient dependency
7. **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[​](#tips-for-building-effective-class-diagrams "Direct link to Tips for Building Effective Class Diagrams")

### Start Simple, Then Add Detail[​](#start-simple-then-add-detail "Direct link to 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[​](#use-namespaces-to-manage-complexity "Direct link to 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[​](#be-consistent-with-visibility "Direct link to 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[​](#label-relationships "Direct link to 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[​](#choose-composition-over-aggregation-deliberately "Direct link to 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[​](#keep-diagrams-focused "Direct link to 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[​](#use-themes-for-visual-consistency "Direct link to 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](/docs/Mermaid-Plus-for-Confluence/usage.md).

## Common Mistakes and How to Fix Them[​](#common-mistakes-and-how-to-fix-them "Direct link to 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[​](#when-to-use-class-diagrams-vs-other-diagram-types "Direct link to 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](/blog/how-to-create-sequence-diagrams-confluence.md)
* **Flowchart** -- Use when documenting processes: decision trees, approval workflows, and algorithmic logic. See [how to create flowcharts in Confluence](/blog/create-flowcharts-confluence.md)
* **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[​](#related-resources "Direct link to Related Resources")

* [Mermaid Plus for Confluence usage guide](/apps/mermaid-plus-for-confluence.md) -- configuration panel walkthrough, theme settings, font and color customization, and all 29 supported diagram types
* [How to create sequence diagrams in Confluence](/blog/how-to-create-sequence-diagrams-confluence.md) -- document message flows between services with copy-paste Mermaid examples
* [Mermaid syntax cheat sheet for Confluence](/blog/faq-mermaid-syntax-cheat-sheet-confluence.md) -- quick reference for flowcharts, sequence diagrams, ER diagrams, and more
* [How to create flowcharts in Confluence](/blog/create-flowcharts-confluence.md) -- 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.

## Related guides

* [How to Create Mermaid Diagrams in Jira](/blog/how-to-create-mermaid-diagrams-jira.md)
* [Export Jira Issues to Excel or CSV](/blog/export-jira-issues-to-excel.md)
* [Bulk Download Jira Attachments](/blog/bulk-download-jira-attachments.md)
* [How to Migrate Confluence Content](/blog/how-to-migrate-confluence-content.md)

Explore NGPILOT[Browse Solutions](/solutions.md)[All Apps](/apps.md)[Atlassian Marketplace →](https://marketplace.atlassian.com/vendors/1226848/?utm_source=ngpilot.com\&utm_medium=blog\&utm_campaign=hub-links)

**Tags:**

* [confluence](/blog/tags/confluence.md)
* [mermaid](/blog/tags/mermaid.md)
* [class-diagram](/blog/tags/class-diagram.md)
* [uml](/blog/tags/uml.md)
* [how-to](/blog/tags/how-to.md)
* [diagrams](/blog/tags/diagrams.md)
