Use case diagrams
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. |
| 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.
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.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.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.
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:useractor guest "Guest" icon=lucide:user-roundactor support "Support agent" icon=lucide:headsetactor bank "Payment provider" type=system side=right icon=lucide:landmarksystem 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-ofguest -- browsecustomer -- cartcustomer -- checkoutsupport -- refundbank -- paybank -- refundcheckout ..> pay : includecoupon ..> checkout : extendActors:
- 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.
usecase "Admin console" desc="What operators and auditors do in the internal admin tool."actor operator "Operator" icon=lucide:user-cogactor auditor "Auditor" icon=lucide:clipboard-checksystem 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 -- usersoperator -- suspendoperator -- usageauditor -- logusers ..> signin : includesuspend ..> signin : includeusage ..> signin : includelog ..> signin : includenote suspend "Every action writes a row to the action log."note auditor "Read only"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.
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:smartphoneactor teller "Branch teller" icon=lucide:user-roundactor core "Core banking" side=right type=system icon=lucide:landmarkactor network "Card network" side=right type=system icon=lucide:credit-cardsystem 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 -- balancecustomer -- transfercustomer -- freezeteller -- openteller -- limittransfer ..> verify : includefreeze ..> verify : includelimit ..> transfer : extendcore -- balancecore -- transfercore -- opennetwork -- freezeActors:
- 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
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.
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 covers the converter in full.
usecase-betadirection LRactor Customeractor SupportsystemBoundary Storefront Browse("Browse catalogue") Checkout("Checkout")endCustomer --> BrowseCustomer --> CheckoutSupport --> CheckoutCheckout ..> : include BrowseThe converter reports the direction it dropped (M202) and the missing title (M214):
usecase
actor Customer "Customer"actor Support "Support"
system Storefront "Storefront" { case Browse "Browse catalogue" case Checkout "Checkout"}
Customer -- BrowseCustomer -- CheckoutSupport -- CheckoutCheckout ..> 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 | The flow, sequence, and schema kinds, and the options every kind shares |
| Swimlane diagrams | How a use case happens, step by step, across the actors |
| C4 diagrams | The people and systems of an architecture, and the containers inside them |
| Migrating from Mermaid | The converter, its diagnostic codes, and what carries over |
| Icon reference | Every icon name you can put in icon= |
| Language reference | Every word of the language, one page for each topic |