Diagram type

PlantUML Activity Diagram Syntax & Examples

Reference for PlantUML activity diagram syntax — start / stop, actions, if-else branches, repeat-while loops, switch-case, and swimlane lanes. Copy-paste examples.

Syntax reference, layout guidance, and ready-to-open examples for this diagram type.

At a glance

A syntax reference for the PlantUML activity-beta grammar — read this when you need to know exactly how a particular construct (decision, loop, lane, fork) is written, then beautify or edit the source in the editor.

What is a PlantUML activity diagramBasic syntax — start, action, stopBranching — if-else and switch-caseLooping — repeat-while and while-doSwimlane lanes — partition responsibility across actorsCommon patterns & gotchas
Syntax reference

PlantUML activity-beta constructs, one per row

ConstructSyntaxNotes
Diagram terminalsstart … stopBoth are required. Omit them and the parser falls back to the legacy (*) syntax.
Action node:Action;Text sits between the colon and the semicolon. A missing ; silently swallows the next line — the most common syntax bug on this grammar.
Two-way decisionif (Condition?) then (yes) … else (no) … endifThe branch labels in parentheses are what appear on the outgoing edges.
Chained decisionelseif (Condition?) then (yes)Chains onto an open if before its else. Repeat as many times as needed.
Multi-way decisionswitch (Test?) case (A) … case (B) … endswitchUse when the branches are named alternatives rather than yes/no.
Test-last looprepeat … repeat while (Condition?) is (yes)Body runs before the test — the do-while shape. Typical for retry patterns.
Test-first loopwhile (Condition?) … endwhileTest runs before the body. Typical for queue processing.
Loop exit label->no;Optional annotation on the exit edge, to say what the false condition means in context.
Swimlane lane|Customer|Declares a lane, or switches to one already declared. Actions belong to the most recent lane.
Coloured lane|#FFB6C1|Monitoring|Named CSS colour or hex. The colour only needs to appear on the first declaration.
Parallel pathsfork … fork again … end forkRenders with the default layout rather than the beautified one.
Branch terminatorstopInside a branch this ends that path only, not the whole diagram.

Syntax reviewed

Rendered proof
A reimbursement approval flow combining swimlane lanes with an if-else decision — the building blocks covered on this page in one diagram.
Theme · Blueprint
Open this diagram in editor
01 Employee 02 Manager 03 Finance yesno 01 · ENTRYStart02 · PROCESSSubmitreimbursement03 · PROCESSReview request04 · DECISIONApproved?05 · PROCESSProcess payment07 · PROCESSNotify employee06 · PROCESSReceive rejection08 · OUTCOMEStop
View PlantUML sourcePlain-text diagram syntax — copy or edit directly.
diagram.puml
1@startuml
2|Employee|
3start
4:Submit reimbursement;
5|Manager|
6:Review request;
7if (Approved?) then (yes)
8 |Finance|
9 :Process payment;
10 :Notify employee;
11else (no)
12 |Employee|
13 :Receive rejection;
14endif
15stop
16@enduml

What is a PlantUML activity diagram

An activity diagram in PlantUML describes a process as an ordered sequence of actions, with branches, loops, and parallel paths along the way. It is the closest PlantUML equivalent to a flowchart — but with a strict grammar (start / :action; / stop) and built-in support for swimlane lanes, which makes it the standard choice for runbooks, approval flows, and process documentation. PlantUML actually ships two activity syntaxes: the legacy one (using (*) and arrow notation) and the modern activity-beta (start / action / stop). Everything on this page covers activity-beta, which is what @startuml / @enduml blocks render by default in current PlantUML releases.

Basic syntax — start, action, stop

Every activity diagram lives inside a @startuml / @enduml block. The flow begins at start, runs through a series of actions written as :Action text; (note the trailing semicolon), and ends at stop (or end for early termination). Actions can be plain strings, multi-line with \n, or include inline formatting. Each action becomes one rounded rectangle in the rendered output, and the renderer connects them top-to-bottom by default. This is the minimum viable activity diagram and the building block every other construct extends.

  • start and stop are required terminals — omit them and the parser falls back to legacy syntax
  • :Action; is the basic activity node — text inside the colons, semicolon at the end
  • Multi-line action labels use \n inside the colons

Branching — if-else and switch-case

Decisions in PlantUML activity use if (Condition?) then (yes) ... else (no) ... endif. The condition is rendered as a diamond, and the (yes) / (no) labels appear on the outgoing edges. For multi-way decisions, use switch (Variable?) ... case (A) ... case (B) ... endswitch — each case becomes a separate path that converges at the end of the switch. Both forms can be nested and combined with loops; the parser handles arbitrarily deep nesting, but practical readability degrades past two levels.

  • if (Condition?) then (yes) ... else (no) ... endif — basic two-way decision
  • if (...) then (yes) ... elseif (...) then (yes) ... else (no) ... endif — chained decisions
  • switch (...) case (A) ... case (B) ... endswitch — multi-way decision with named branches

Looping — repeat-while and while-do

PlantUML activity offers two loop constructs that differ in when the condition is evaluated. repeat ... repeat while (Condition?) is (yes) runs the body first, then tests — equivalent to a do-while loop. while (Condition?) ... endwhile tests first, then runs the body — equivalent to a standard while loop. The first form is typical for retry patterns (attempt the action, then check whether to retry); the second is typical for queue processing (check whether there's work, then process it). Both forms accept an optional ->no; or ->yes; annotation on the exit edge to label what the false condition means in context.

Swimlane lanes — partition responsibility across actors

Swimlane lanes are PlantUML activity's standout feature. Declare a lane with |Lane Name| before the first action that belongs in it; subsequent actions belong to the most recently declared lane until another |Other Lane| switches context. Optionally tint the lane with |#Color|Lane Name| — colors can be named CSS values or hex. The reference renderer stacks lanes vertically as subgraphs, but Beauty Diagram's renderer lays them out as horizontal columns by default once at least two lanes and one cross-lane edge are present. That column layout is what makes the diagram read as a process across actors rather than a vertical sequence with labels.

  • |Customer| — plain lane declaration
  • |#FFB6C1|Monitoring| — coloured lane declaration with hex tint
  • |Lane Name| re-used later switches the active lane without redefining it

Common patterns & gotchas

A few patterns come up repeatedly. Approval flows usually combine swimlanes with if-else — the approver lane has the decision, the receiver lane handles each outcome. Retry flows pair repeat-while with a status check. Forks and joins for parallel paths use fork ... fork again ... end fork — supported but rendered with default layout, not yet beautified. The most common gotcha: forgetting the semicolon on :Action; causes the parser to swallow the entire next line silently — if your diagram is missing a node, check the previous line for a missing ; first.

  • Missing ; on :Action; silently swallows the next line — most common syntax bug
  • Lanes only switch to horizontal columns when ≥ 2 lanes + ≥ 1 cross-lane edge exist
  • stop inside a branch terminates only that branch path, not the whole diagram
FAQ

PlantUML Activity Diagram Syntax & Examples — frequently asked questions

What does start and stop do in a PlantUML activity diagram?

start marks the entry point (rendered as a filled black circle) and stop marks the exit (a circled black dot). Both are required for the activity-beta syntax; without them, the parser falls back to PlantUML's legacy activity syntax which has different semantics. Use end instead of stop for an early-termination terminal that visually differs from a normal exit.

How do I write an if-else decision in PlantUML activity syntax?

Use if (Question?) then (yes) ... else (no) ... endif. The question becomes a diamond node, and the (yes) / (no) strings label the outgoing edges. For multi-way decisions, chain with elseif (Other?) then (yes) ... or use switch (Variable?) case (A) ... case (B) ... endswitch. Both forms render with the same visual conventions.

What's the difference between repeat-while and while-endwhile?

repeat ... repeat while (Condition?) is (yes) is a do-while loop — the body runs once before the condition is checked. while (Condition?) ... endwhile is a standard while loop — the condition is checked first, and the body may never run. Use repeat-while for retry patterns (always attempt at least once), and while-endwhile for queue processing or polling (check first before doing work).

Can I nest swimlane lanes inside other constructs?

Lanes themselves cannot be nested — there's no |Outer| |Inner| syntax. But you can switch lanes inside any other construct: inside an if-else branch, inside a repeat loop, anywhere an action would be valid. The lane scope follows the source order, so each |Lane| declaration switches the active lane until the next one. Beauty Diagram preserves whichever lane is active at each action when laying out horizontal columns.

Why does my activity diagram look vertical instead of horizontal?

Two reasons. First, the default PlantUML renderer always stacks lanes vertically — switch to the Beauty Diagram editor to get the horizontal column layout. Second, even Beauty Diagram only flips to horizontal columns when at least two |lane| declarations exist AND at least one edge crosses between lanes — a single-lane diagram or a diagram where all actions stay in one lane stays vertical because there's no swimlane signal to render.