# Use case diagrams

> Page: https://docs.plotwork.dev/use-case-diagrams. Index of every page: https://docs.plotwork.dev/llms.txt

A use case diagram shows who uses a system and for what: the actors outside it, the system boundaries, the use cases each system offers, and how the use cases depend on each other. Use it to scope a product or a feature, to agree what is in a release, or to open a requirements document. It is for anyone, human or AI agent, who needs the answer to "who does what with this system".

## TL;DR

| Question | Answer |
|---|---|
| What is it for? | The scope of a system: its actors, the use cases they take part in, and include, extend, and kind-of between them. A flow shows how something happens; a use case diagram shows what can happen and for whom. |
| How does it start? | `usecase "Title"`, then `actor id "Name"`, then `system id "Name" {` with `case id "Label"` lines inside it, then a link such as `customer -- checkout`. |
| Where do the parts go? | Primary actors stand on the left, supporting actors (`side=right`) on the right, and the systems in the middle with their use cases in a column. Layout is automatic. |
| How do use cases relate? | `a ..> b : include` when a always does b, `a ..> b : extend` when a adds to the base case b, and `a -> b : kind-of` when a is a kind of b. |
| Can I convert Mermaid? | Yes. Mermaid `usecase-beta` converts with the `convert_mermaid` tool. See [From Mermaid](#from-mermaid). |
| How big may it be? | 100 use cases, 30 actors, 4 systems, and 300 links. Past a limit the diagram is refused with error `E140`. |
| How is it drawn? | A person is a round badge and a system a square one, with the name under it; a use case is a pill; a system is a frame with its name in the corner. The theme chooses every color. |

## Ask your agent

Name the actors and what each one does, say which ones support the system rather than use it, and say which use cases always include another.

```text
Use Plotwork to draw a use case diagram of our online shop. Customers browse the catalogue, manage the cart, and check out; a guest is a kind of customer who can only browse. Checking out always includes paying by card, and applying a coupon extends a checkout. A support agent refunds orders, and the payment provider is a supporting system on the right that takes part in paying and refunds.
```

```text
Use Plotwork to draw the use cases of our internal admin console. An operator looks up accounts, suspends an account, and reads usage totals; an auditor reads the action log. Every one of those includes signing in with a code. Add a note on suspending that every action writes a row to the action log.
```

```text
Use Plotwork to draw a use case diagram of mobile banking with two systems, the mobile app and the branch desk. The customer checks the balance, transfers money, and freezes a card in the app, and transfers and freezes include Face ID. A branch teller opens accounts and raises limits, and raising a limit extends a transfer. Core banking and the card network are systems on the right.
```

## Example

This is the online shop from the first prompt. It shows a generalisation between two actors, an include and an extend between use cases, and a supporting system on the right.

**Diagram source**

```diagram
usecase "Online shop" desc="What customers, guests and the payment provider do with the shop. Checking out always includes paying, and a coupon can extend a checkout."
actor customer "Customer" icon=lucide:user
actor guest "Guest" icon=lucide:user-round
actor support "Support agent" icon=lucide:headset
actor bank "Payment provider" type=system side=right icon=lucide:landmark
system shop "Shop" icon=lucide:store {
  case browse "Browse the catalogue"
  case cart "Manage the cart"
  case checkout "Check out"
  case pay "Pay by card"
  case coupon "Apply a coupon"
  case refund "Refund an order"
}
guest -> customer : kind-of
guest -- browse
customer -- cart
customer -- checkout
support -- refund
bank -- pay
bank -- refund
checkout ..> pay : include
coupon ..> checkout : extend
```

*Picture: Online shop: 4 actors, 6 use cases in 1 system, 9 links. What customers, guests and the payment provider do with the shop. Checking out always includes paying, and a coupon can extend a checkout.*

**Text description**

**Actors:**

- Customer (person): takes part in Manage the cart, Check out
- Guest (person): a kind of Customer; takes part in Browse the catalogue
- Support agent (person): takes part in Refund an order
- Payment provider (system, supporting): takes part in Pay by card, Refund an order

**Systems:**

- Shop
  - Browse the catalogue
  - Manage the cart
  - Check out
  - Pay by card
  - Apply a coupon
  - Refund an order

**Relations:**

- Check out includes Pay by card
- Apply a coupon extends Check out
- Guest is a kind of Customer

### An internal admin tool

Every use case of the admin console includes signing in, so the four includes meet the sign-in case as one line with one arrowhead. A note under the auditor says it reads only, and a note beside the systems is attached to the case it is about by a dotted line.

**Diagram source**

```diagram
usecase "Admin console" desc="What operators and auditors do in the internal admin tool."
actor operator "Operator" icon=lucide:user-cog
actor auditor "Auditor" icon=lucide:clipboard-check
system admin "Admin console" icon=lucide:shield tone=blue {
  case signin "Sign in with a code"
  case users "Look up an account"
  case suspend "Suspend an account" tone=red sub="Needs a typed reason"
  case usage "Read usage totals"
  case log "Read the action log"
}
operator -- users
operator -- suspend
operator -- usage
auditor -- log
users ..> signin : include
suspend ..> signin : include
usage ..> signin : include
log ..> signin : include
note suspend "Every action writes a row to the action log."
note auditor "Read only"
```

*Picture: Admin console: 2 actors, 5 use cases in 1 system, 8 links. What operators and auditors do in the internal admin tool.*

**Text description**

**Actors:**

- Operator (person): takes part in Look up an account, Suspend an account, Read usage totals
- Auditor (person): takes part in Read the action log

**Systems:**

- Admin console
  - Sign in with a code
  - Look up an account
  - Suspend an account (Needs a typed reason)
  - Read usage totals
  - Read the action log

**Relations:**

- Look up an account includes Sign in with a code
- Suspend an account includes Sign in with a code
- Read usage totals includes Sign in with a code
- Read the action log includes Sign in with a code

**Notes:**

- On Suspend an account: Every action writes a row to the action log.
- On Auditor: Read only

### A mobile banking app with two systems

Two systems stack down the middle, each in its own frame and tone. The supporting systems stand on the right, and the extend from the branch desk to the app crosses from one frame to the other on its own track.

**Diagram source**

```diagram
usecase "Mobile banking" desc="A customer banks on the phone; the bank's core and the card network do the work behind it."
actor customer "Customer" icon=lucide:smartphone
actor teller "Branch teller" icon=lucide:user-round
actor core "Core banking" side=right type=system icon=lucide:landmark
actor network "Card network" side=right type=system icon=lucide:credit-card
system app "Mobile app" icon=lucide:smartphone tone=violet {
  case balance "Check the balance"
  case transfer "Transfer money"
  case freeze "Freeze a card"
  case verify "Verify with Face ID"
}
system branch "Branch desk" icon=lucide:building {
  case open "Open an account"
  case limit "Raise a limit"
}
customer -- balance
customer -- transfer
customer -- freeze
teller -- open
teller -- limit
transfer ..> verify : include
freeze ..> verify : include
limit ..> transfer : extend
core -- balance
core -- transfer
core -- open
network -- freeze
```

*Picture: Mobile banking: 4 actors, 6 use cases in 2 systems, 12 links. A customer banks on the phone; the bank's core and the card network do the work behind it.*

**Text description**

**Actors:**

- Customer (person): takes part in Check the balance, Transfer money, Freeze a card
- Branch teller (person): takes part in Open an account, Raise a limit
- Core banking (system, supporting): takes part in Check the balance, Transfer money, Open an account
- Card network (system, supporting): takes part in Freeze a card

**Systems:**

- Mobile app
  - Check the balance
  - Transfer money
  - Freeze a card
  - Verify with Face ID
- Branch desk
  - Open an account
  - Raise a limit

**Relations:**

- Transfer money includes Verify with Face ID
- Freeze a card includes Verify with Face ID
- Raise a limit extends Transfer money

## The language

A line is one statement. A `#` starts a comment. Ids are words such as `checkout`, `pay-card` or `_x`, labels are in double quotes, and options are written `key=value`. The first line is the header.

### The header

```plotwork
usecase "Online shop" desc="What customers do with the shop."
```

| Part | Meaning |
|---|---|
| `usecase` | The kind. |
| `"Title"` | The title. It is the accessible name of the picture and heads the text description. Optional. |
| `desc=` | A plain-language description for the text description. Optional. A `desc "text"` statement does the same. |

### Statements

| Statement | Meaning | Example |
|---|---|---|
| `actor <id> "Name" type=<person\|system> side=<left\|right> tone=<tone> icon=<set:name>` | An actor. | `actor bank "Bank" type=system side=right` |
| `system <id> "Name" tone=<tone> icon=<set:name> {`, the cases inside, then `}` | A system boundary. The `}` is on a line of its own. | `system shop "Shop" icon=lucide:store {` |
| `case <id> "Label" sub="Detail" tone=<tone>` | A use case, inside a system's block or outside every system. | `case checkout "Check out"` |
| `<actor> -- <case> : "label"` | An association. The label is optional. | `customer -- checkout` |
| `<a> -> <b> : "label"` | An association with an arrowhead at `b`. | `pay -> bank : "charge"` |
| `<case> ..> <case> : include` | The first case always does the second. | `checkout ..> pay : include` |
| `<case> ..> <case> : extend` | The first case adds to the second, the base case. | `coupon ..> checkout : extend` |
| `<case> ..> <case> : "label"` | A plain dependency, dashed, with its label. | `export ..> signin : "after"` |
| `<a> -> <b> : kind-of` | A generalisation: a is a kind of b. | `guest -> customer : kind-of` |
| `note <id> "Text"` | A note on an actor or a use case. | `note checkout "Needs a session"` |
| `desc "text"` | The description of the diagram. | `desc "What the shop offers."` |

`tone=` takes `neutral`, `blue`, `violet`, `aqua`, `orange`, `green`, `amber`, or `red`, and `icon=` takes a name from the closed list of icons, such as `lucide:user` or `simple:stripe`. A diagram cannot set a color: the theme chooses every color, in light and dark.

### Actors and systems

An actor is someone or something outside the systems that takes part in a use case. A person is drawn as a round badge in violet and a system as a square badge in blue, each with its icon and its name under it. Write `type=system` for an API, a bank, or another system; an actor whose icon comes from a brand or cloud set, such as `simple:stripe`, is a system unless `type=` says otherwise.

Primary actors, who use the system, stand on the left. Write `side=right` on a supporting actor, one the system calls or relies on, so it stands on the right. Each actor stands at the height of the use cases it takes part in, so the association lines cross little.

A system is a frame with its name and icon in the top-left corner, and the use cases it offers are inside its block. A diagram has up to 4 systems, stacked down the middle, and they are one level deep. A use case written outside every block stands below the systems, outside any frame.

### Use cases

A use case is a pill that grows to fit its name, and its name wraps to three lines. `sub=` adds a line under the name, for a detail or a condition. A `tone=` tints the pill: green for a good outcome, amber for a warning, and red for something that needs care.

### Include, extend, and kind-of

| Written | Drawn | Read it as |
|---|---|---|
| `a ..> b : include` | A dashed line with an arrowhead at `b` and «include» in a pill | a always does b, as a part of itself. |
| `a ..> b : extend` | A dashed line with an arrowhead at `b` and «extend» in a pill | a adds to b, the base case, in some situations. |
| `a ..> b : "label"` | A dashed line with an arrowhead at `b` and the label in a pill | a depends on b in the way the label says. |
| `a -> b : kind-of` | A solid line with a hollow triangle at `b` | a is a kind of b. Both are actors, or both are use cases. |
| `a -- b` | A solid line | An actor takes part in a use case. |
| `a -> b` | A solid line with an arrowhead at `b` | An actor or a use case that calls or tells the other. |

Include and extend join two use cases, and a kind-of joins two actors or two use cases; anything else is an error that says what to write. A link between two use cases runs on a track beside the column of use cases, on the side with fewer actors, so it never crosses another use case. Links of one kind that arrive at one use case meet it as one line with one arrowhead. A kind of an actor stands directly below the actor it is a kind of, joined by a short line up the column.

### Notes

`note <id> "Text"` attaches a note to an actor or a use case. A note on an actor is drawn under its name. A note on a use case stands in a column right of the systems, joined to its use case by a dotted line. Two notes on one actor are joined into one.

```plotwork
note checkout "Needs a signed-in customer"
```

## Limits and warnings

Warnings never stop a diagram from being drawn. Errors do.

| Limit | Value | What happens past it |
|---|---|---|
| Use cases | 100 | `E140` |
| Actors | 30 | `E140` |
| Systems | 4 | `E140` |
| Links | 300 | `E140` |
| Notes | 60 | `E140` |
| Use cases before the density warning | 30 | `W200` |
| Actors before the density warning | 10 | `W200` |

| Code | Severity | When | Fix |
|---|---|---|---|
| `E100` | error | A system with no block, a system inside a system, an actor or a link inside a system, an arrow a link cannot have, a link to itself, an include or extend that touches an actor, a kind-of between an actor and a use case, or an association between two actors. | Each says what to write. |
| `E131` | error | A link or a note names an id that is not an actor or a use case, or names a system. | Declare it first, or link to a use case inside the system. |
| `E136` | error | A link word that its arrow does not take, such as `includes`, or a `side=` or `type=` that is not one of its values. | The hint lists the words. |
| `E140` | error | The diagram is over a limit in the table above. | Split the diagram. |
| `W200` | warning | More than 30 use cases or 10 actors. | Draw one diagram for each system or each group of actors. |
| `W201` | warning | An actor with no link, a use case no actor reaches directly or through include and extend, a system with no use case, or an include that loops back to itself. | Link it, include it, or remove it. |
| `W202` | warning | The diagram is wider than a column keeps readable. | Shorten the names, or put fewer actors on the right. |
| `W203` | warning | Text was cut with an ellipsis. | Shorten the text, or move detail into `sub=`. |

The header alone is a valid diagram, drawn empty, so a new diagram can start from it. The layout is plain arithmetic, so even a diagram at the limits is laid out in a few milliseconds.

## From Mermaid

Mermaid `usecase-beta` (and `usecase`, as Mermaid is likely to name it once it leaves beta) converts to a use case diagram. Ask your agent to convert it, or use the `convert_mermaid` tool. The [migration guide](https://docs.plotwork.dev/migrating-from-mermaid.md) covers the converter in full.

```mermaid-source
usecase-beta
direction LR
actor Customer
actor Support
systemBoundary Storefront
  Browse("Browse catalogue")
  Checkout("Checkout")
end
Customer --> Browse
Customer --> Checkout
Support --> Checkout
Checkout ..> : include Browse
```

The converter reports the direction it dropped (`M202`) and the missing title (`M214`):

```plotwork
usecase

actor Customer "Customer"
actor Support "Support"

system Storefront "Storefront" {
  case Browse "Browse catalogue"
  case Checkout "Checkout"
}

Customer -- Browse
Customer -- Checkout
Support -- Checkout
Checkout ..> Browse : include
```

| Mermaid | Plotwork | Report |
|---|---|---|
| `actor A`, `actor A("Label")` | `actor A "Label"` | none |
| `U("Label")`, `"Label"`, an id met only in a link | `case U "Label"` | none |
| `U[Label]`, a rectangle | `case U "Label"`, a pill | `M204` |
| `systemBoundary s["Title"]` to `end` | `system s "Title" {` to `}` | none |
| `@{ type: package }` on a boundary, `@{ type: hollow }` or `awesome` on an actor | Dropped; one look for each | `M204` |
| An actor inside a boundary | Drawn beside the systems | `M204` |
| `Actor --> UseCase`, `<--`, `--` | `Actor -- UseCase`, a plain association | none |
| `UseCase --> Actor`, `UseCase --> UseCase` | `->`, with its arrowhead | none |
| `--o`, `o--`, `--x`, `x--` | A plain association | `M204` |
| `A -- "label" --> B` | `A -- B : "label"` | none |
| `A ..> : include B`, `A ..> : extend B` | `A ..> B : include`, `A ..> B : extend` | none |
| `A --\|> B` | `A -> B : kind-of` | none |
| `note for U "text"` | `note U "text"` | none |
| `<<Stereotype>>` on a use case | The use case's `sub=`, as «Stereotype» | `M204` |
| `<<Stereotype>>` on an actor, `business: true` | Dropped | `M203` |
| An association between two actors, include or extend that touches an actor | Dropped | `M203` |
| `json` tables | Dropped | `M203` |
| `direction`, edge ids `e1@`, extra dashes `--->` | Dropped | `M202` |
| `classDef`, `class`, `style`, `:::class`, metadata statements | Dropped | `M200` |
| `icon:` on an actor | Dropped. Plotwork icons are a closed set. | `M215` |
| Markdown strings and HTML in a label | Cleaned to plain text | `M205` |
| A link repeated exactly | Dropped | `M209` |
| A boundary that is never closed, an `end` with nothing to close | Repaired | `M217` |
| A title in front matter or `accTitle:`, and `accDescr:` | The title and `desc=` | none |

## See also

| Doc | Why |
|---|---|
| [Writing diagrams](https://docs.plotwork.dev/writing-diagrams.md) | The flow, sequence, and schema kinds, and the options every kind shares |
| [Swimlane diagrams](https://docs.plotwork.dev/swimlane-diagrams.md) | How a use case happens, step by step, across the actors |
| [C4 diagrams](https://docs.plotwork.dev/c4-diagrams.md) | The people and systems of an architecture, and the containers inside them |
| [Migrating from Mermaid](https://docs.plotwork.dev/migrating-from-mermaid.md) | The converter, its diagnostic codes, and what carries over |
| [Icon reference](https://docs.plotwork.dev/reference/icons.md) | Every icon name you can put in `icon=` |
| [Language reference](https://docs.plotwork.dev/reference/language.md) | Every word of the language, one page for each topic |
