Applicable version: this documentation is based on PlantUML 1.2025.3 (June 2025), which introduces new syntaxes (notably CSS-style styling) and removes some legacy commands.
PlantUML is a text‑based language for creating both UML and non‑UML diagrams. Every diagram starts with @start… and ends with @end…. The type of diagram is defined in the start tag (uml, mindmap, nwdiag, etc.). Comments are written with // or /'…'/. The title, header, footer, legend and caption directives are common to all diagrams and add contextual information.
Every diagram begins with @startuml (or a more specific type such as @startmindmap) and ends with @enduml. The type must remain consistent throughout the file.
Elements (participants, classes, objects, etc.) can be created implicitly by referring to them in messages or relations. However, it is recommended to declare them explicitly (using participant, class, entity, etc.) to define their type or style.
PlantUML historically used the skinparam directive to adjust colours, fonts and margins. This directive is being phased out in favour of the CSS‑like style mechanism introduced in 2019.9. The « Skinparam » page recommends using style for most customisation, although skinparam is still supported for simple cases (plantuml.com).
Styles are defined in a <style> block: each selector (e.g. sequenceDiagram, class, network) accepts properties like BackgroundColor, FontColor, LineColor, LineStyle, FontSize, RoundCorner, etc. Styles can also be applied via stereotypes (<<stereo>>) or CSS classes (.myStyle) (plantuml.com). The style mechanism accepts dynamic selectors (:root, :level(2)) and allows global modifications. Predefined themes can be loaded with !theme dark or via the preprocessor function %get_all_theme().
PlantUML includes a C‑like preprocessor to define variables, functions, loops and conditionally generate code. Global variables are declared with !$var = value; they can be assigned conditionally using !$var ?= value (plantuml.com). Conditions use !if, !elseif and !endif and support operators &&, || and parentheses (plantuml.com). Loops use !while … !endwhile (plantuml.com). Reusable code can be defined via !procedure (no return value) or !function (returns a value) (plantuml.com). The !include directive loads libraries and replaces the legacy macros !define/!definelong (plantuml.com). Built‑in functions such as %get_all_theme() and %get_all_stdlib() return the list of available themes or libraries (plantuml.com).
Syntax: declare participants explicitly with participant, actor, boundary, control, entity or database. Messages use -> for a solid arrow or --> for a dashed arrow (asynchronous). A reply is drawn by reversing the direction. Example:
@startuml
actor Alice #lightblue
participant Bob
Alice -> Bob : Request
Bob --> Alice : Response
@endumlIn this diagram, Alice and Bob are declared; a colour can be specified (#lightblue). Solid arrows represent synchronous calls and dashed arrows represent asynchronous returns (plantuml.com). Participants can be created implicitly by naming them in a message, but it is better to declare them to set their type or colour (plantuml.com).
Special messages:
- Self call:
participant A; A -> A : messagedraws a loop. - Lost/found messages:
->ooro->represent a lost or found message. - Text alignment and position:
skinparam sequenceMessageAlignaligns text left, centre or right;skinparam responseMessageBelowArrowmoves response text below the arrow.
Groups and operators:
- Box:
box "title" #backgroundColor … end boxsurrounds participants. - alt / else / end: alternatives.
- opt / end: optional path.
- loop / end: loop with a condition.
- parallel / end (or
par): parallel operations.
Notes and legends: note left of A or note over A,B adds a comment. The legend directive adds a global legend.
Classes are created with class, abstract, interface, enum, record, struct, etc. Relationships are drawn using the following connectors:
| Relationship | UML syntax | Meaning |
|---|---|---|
| Inheritance (extension) | Parent <|-- Child |
open arrow |
| Implementation | Interface <|.. Class |
dashed arrow |
| Association | Class1 -- Class2 |
solid line |
| Dependency | Class1 ..> Class2 |
dashed line |
| Aggregation | Class1 o-- Class2 |
white diamond |
| Composition | Class1 *-- Class2 |
black diamond |
Lines can be dotted by replacing -- with .. (plantuml.com). The arrow can be reversed to change direction. A label is added after : label or a cardinality is set in quotes: Class1 "1" o-- "many" Class2 (plantuml.com).
Members are declared inside braces with + (public), - (private), # (protected):
@startuml
class User {
-id : Integer
+name() : String
}
@endumlGeneric classes are noted class Stack<T>. Packages or modules are created with package P { … }. Stereotypes (<<Entity>>) and colours (#lightyellow) allow further customisation.
Actors are declared with actor or by enclosing the name in double colons (:User:). Use cases are drawn inside parentheses or via usecase. Example:
@startuml
actor Client
usecase (Book a flight) as UC1
Client --> UC1
@endumlRelations are drawn with simple arrows (-->) and may be annotated with keywords (<<include>>, <<extend>>) to specify the type of relationship. Arrow length varies with the number of dashes (---> lengthens the arrow). You can orient the arrow (--> left) or reverse it. Actors and use cases can be grouped into package blocks or rectangle frames. Actor appearance can be modified: skinparam actorStyle hollow draws stickmen, while awesome uses icons (plantuml.com).
The recommended “beta” syntax no longer depends on Graphviz. Actions are written with : followed by the action and end with a ;. Diagrams start with start and end with stop or end:
@startuml
start
:Read request;
if (Valid request?) then (yes)
:Process request;
else (no)
stop
endif
@endumlConditional branching uses if … then … else … endif; elseif can be added. Actions are separated by semicolons. Loops use repeat … repeat while (<condition>) and may have a backward branch (plantuml.com). Parallel processing is defined with fork / fork again … end fork or split / split again … end split (plantuml.com). The left to right direction directive changes orientation. Notes (note) can be inserted, actions can be coloured (:Action #palegreen;) and switches can be drawn with switch / case / endswitch.
Components are represented by tabbed boxes and are defined with component or by enclosing the name in brackets []. Examples:
@startuml
[First component]
component Second as Comp2
interface ICache
Comp2 --> ICache
@endumlAn alias (as) is used to reuse short names. Interfaces are indicated with (), as in () "Database" (plantuml.com). Relationships use -- or .. (dotted), and > for directional arrows (A --> B). Components may be placed inside node, folder, database or cloud elements representing deployment nodes. Logical groups are organised with package or frame. Physical components (artifacts) are defined with artifact.
The symbol [*] represents the initial or final state. States are named and transitions use arrows --> with an optional label:
@startuml
[*] --> Open
Open --> Closed : close()
Closed --> Open : open()
@endumlComposite states are created with state <Name> { … }. Sub‑states can be nested and transitions drawn between them. The hide empty description attribute hides empty boxes for a simpler rendering (plantuml.com). Internal transitions are expressed by placing the event after : (e.g. state A : entry / exit). Notes can be added with note.
Deployment diagrams describe the physical architecture of a system. PlantUML offers several shapes: node (server or VM), database, cloud, folder, artifact, etc. The syntax is similar to component and deployment diagrams. Example:
@startuml
node "Web Server" {
[App] --> [Database]
}
cloud "Internet" {
[User] --> [App]
}
@endumlThe deployment page lists all available elements: actor, agent, artifact, boundary, circle, component, control, database, entity, file, folder, frame, hexagon, interface, label, node, package, person, process, queue, rectangle, stack, storage, usecase (plantuml.com). Multi‑line labels are created using separators ---, ===, .... Orientation can be set with left to right direction. Elements can be nested (a node containing several components) and connected by arrows.
Object diagrams depict instances of classes. They are created with object or by enclosing the name in braces. Fields are defined after : and separated by new lines:
@startuml
object User {
name = "Alice"
id = 123
}
object Session
User --> Session : « 1..* »
@endumlRelationships use the same syntax as class diagrams (association, composition, etc.) (plantuml.com). Cardinalities are written in quotes or after a :. Associations may pass through an associative object represented by a diamond.
Timing diagrams visualise sequences of states over time. Several participant types exist:
| Type | Description |
|---|---|
robust |
Tracks an object’s behaviour (name + state) |
concise |
Summarises several states |
analog |
Continuous numeric value |
binary |
Binary state (high/low) |
clock |
Reference oscillator |
For each participant, states are defined at a time @; the time may be absolute (@ 0 is Idle) or relative (@+100 is Running, meaning 100 units after the last definition). Messages can be sent at a time: WU -> WB : URL (plantuml.com). Anchor points can be named via @+100 as Anchor and referenced elsewhere. Scales are defined with scale xN or scale <duration> as <value> to convert time units to pixels (plantuml.com).
Gantt diagrams plan tasks. Tasks are declared with []:
@startgantt
[Analysis] lasts 10 days
[Development] starts at [2025-07-01] and lasts 4 weeks
[Deployment] starts after [Development] and lasts 5 days
@endganttA task can start at an absolute date (2025-07-01), relatively (D+5 means five days after the project start) or after another task (after [Task]). Duration is expressed in days, weeks or months using lasts or requires. Closing periods (weekends) are defined via saturday are closed or sunday are closed, which affects duration: a week equals the number of non‑closed days (plantuml.com). Resources or responsibilities can be attached to a task with as, and milestones defined using happens. Tasks can be grouped, progress indicated and bars coloured via styling.
Mind maps (@startmindmap) and WBS (@startwbs) show hierarchies. Nodes are defined by stars or plus signs: * (or +) for level 1, ** for level 2, etc. Example:
@startmindmap
* Project
** Ideation
*** Research
** Development
@endmindmapThe symbol < places a sub‑branch to the left and > to the right (mostly used in WBS). Multi‑line labels are created with :title: description, and styles can be defined per depth. WBS diagrams break down a project into tasks; the rules are the same but oriented toward project management (plantuml.com).
@startjson and @startyaml diagrams convert data structures directly into diagrams. Content is inserted verbatim. Keys can be highlighted with #highlight to colour a path. For example:
@startjson
{ "person": { "name": "Alice", "address": { "city": "Montreal" } } }
#highlight person.name
@endjsonPaths use / to access subkeys. Styles can be customised via <style> targeting json or yaml and by applying classes (e.g. .h1) to colour highlighted elements (plantuml.com). Keys containing special characters or symbols must be quoted (plantuml.com).
nwdiag diagrams represent networks and devices. Basic syntax:
@startuml
nwdiag {
network dmz {
address = "210.x.x.x/24"
web01 [address = "210.x.x.1"]
web02 [address = "210.x.x.2"]
}
}
@endumlnetwork blocks contain hosts (e.g. web01) with IP addresses (plantuml.com). Networks may be nested and group blocks group devices and set colours or shapes (plantuml.com). Networks can define properties such as address, color, description, shape and width = full to normalise width (plantuml.com). Sprites or icons can be used in a host’s description (description = <$server><$printer> Server) or via the OpenIconic syntax <&icon> (plantuml.com). Direct connections between networks can be declared outside blocks (e.g. inet -- router; network { … }).
Global styles are defined via <style> targeting network, server, arrow, etc., to modify background colours, line colours, thickness, margins and fonts (plantuml.com). A title, header, footer, legend or caption can be added after the nwdiag block (plantuml.com).
PlantUML provides the “Salt” library for drawing wireframe user interfaces. Diagrams start with @startsalt or with salt { … } inside an UML diagram. A window is defined by a { … } block and contains widgets:
| Widget | Syntax | Description |
|---|---|---|
| Button | [OK] |
triggers an action |
| Text field | "" |
entry field; spaces set width (plantuml.com) |
| Check box | [ ], [X] |
empty or checked |
| Radio button | ( ), (o) |
empty or selected |
| Drop-down list | ^ |
arrow icon shows a menu |
Table lines can be separated with | to create a table. Prefixing the opening brace with # shows all grid lines, ! shows only vertical lines, - only horizontal lines and + just the outer border (plantuml.com). Scrollbars are added by appending S (both directions), SI (vertical only) or S- (horizontal only) after the opening brace (plantuml.com). Horizontal separators are created with .. (dotted), == (double), ~~ (wavy) or -- (solid) (plantuml.com)..%2C%20%3D%3D%2C%20,. Group boxes are created by prefixing the window with a caret and a title (plantuml.com).
Additional widgets:
- Trees: start with
{Tand use+for indentation; variantsT!,T-,T+,T#define grid lines in a tree table (plantuml.com). - Tabs and menus:
{/\nTab1|Tab2\n}creates horizontal tabs; the selected tab is repeated below the bar. Menus are written with*and|to separate options (plantuml.com).
Salt allows colour formatting via <color:name> or [#hex] and supports creole/HTML‑like markup for bold, italics, strike‑through, underline and highlighting (plantuml.com). Pseudo‑sprites (<<mySprite>>) let you define reusable icons (plantuml.com). OpenIconic icons are accessible via <&icon> (plantuml.com). You can embed a Salt block inside another diagram by surrounding it with {{ … }}, for example inside an activity diagram to display a form (plantuml.com). Salt macros create reusable panels: define a procedure !procedure SALT(name) { … } and call it with SALT(MyPanel) (plantuml.com). Styles apply via skinparam (some properties) or via <style> targeting saltDiagram (plantuml.com).
ArchiMate is an enterprise architecture modelling language. PlantUML provides elements via the archimate keyword. Example:
@startuml
archimate #Technology "VPN Server" as vpn <<technology-device>>
@endumlElements are typed via stereotypes (<<business-process>>, <<application-component>>, etc.). Standard macros are available in the archimate library (via !include <archimate/Archimate>), for instance Motivation_Stakeholder(name, description) or Business_Service(name, description) (plantuml.com). Relationships between elements are defined using macro connectors (e.g. Rel_Composition_Down(Element1, Element2, "Desc")) to specify type and orientation (Access, Aggregation, Assignment, Association, Composition, Flow, Influence, Realization, Serving, Specialization, Triggering) (plantuml.com).
To represent OR/AND junctions, you can define circle macros and use them as objects (!define Junction_Or circle #black) (plantuml.com). Element colours can be chosen (#Application, #Business, #Technology) to indicate layers (Business, Application, Technology) (plantuml.com).
@startregex diagrams generate explanatory diagrams for regular expressions. The content is a standard regular expression. Examples:
@startregex /hello\d+/ @endregexshows a block forhellofollowed by one or more digits (\d+) (plantuml.com).- Quantifiers
?,+,*,{n,m}are represented by loops and branches. PlantUML shows the notation and may display a brief note; equivalences such as{0,1}and?are explained (plantuml.com). - Alternatives are shown by branches (
a|b) (plantuml.com). Unicode categories (\p{L}for any letter,\p{Latin}for the Latin script) and blocks (\p{InGeometric_Shapes}) can be visualised (plantuml.com). - Descriptive names can be enabled with
!option useDescriptiveNames trueand a language selected (!option language en,de,ja, etc.) to translate labels (plantuml.com).
@startebnf diagrams illustrate formal grammars. The syntax follows classic EBNF: rule = expression ;. Example:
@startebnf
binaryDigit = "0" | "1";
@endebnfHandled elements include literals ("a"), optional sequences ([a]), zero or more repetitions ({a}), one or more (a, {a}) or the EBNF variant ({a}-), and alternatives (a | b) (plantuml.com). Special sequences are written ? … ?, e.g. ? Unicode U+0009 ? (plantuml.com). The repetition n * a requires exactly n occurrences, and m * a, b means m occurrences followed by the separator b (plantuml.com). PlantUML provides a “compact” mode (no longer needed since v1.2025.1) to reduce space (plantuml.com). EBNF diagrams can be styled via <style> targeting element.ebnf to change line colours or the background of notes (plantuml.com).
IE (relational model): entities are declared with entity (equivalent to class). Cardinalities use specific connectors:
| Connector | Meaning |
|---|---|
|o-- |
zero or one (0..1) |
||-- |
exactly one (1) |
}o-- |
zero or many (0..*) |
}|-- |
one or many (1..*) |
Example:
@startuml
entity Author {
* id : INTEGER
name : STRING
}
entity Book {
* id : INTEGER
title : STRING
}
Author ||--o{ Book
@endumlThe * before an attribute marks it as mandatory. Separate the list of attributes with -- to display an “optional” compartment (plantuml.com).
Chen model: @startchen diagrams use notation where entities and relationships are separate objects. Entities are written entity Name { … } and relationships relationship Name { … }. Connect entities and relationships using -1- (one), -N- (many), etc. Example:
@startchen
entity Person
relationship Birthplace
entity Location
Person -N- Birthplace
Birthplace -1- Location
@endchenAttributes can be composite (broken down) by nesting braces: Name { Fname Lname } (plantuml.com). Attributes may be marked as <<key>> (key), <<derived>> (derived) or <<multi>> (multivalued) (plantuml.com).
skinparam quickly adjusts certain parameters. Examples:
- Enable monochrome:
skinparam monochrome true(plantuml.com). - Set a participant’s background colour:
skinparam ParticipantBackgroundColor #E0E0E0. - Remove shadow:
skinparam shadowing false(plantuml.com).
skinparam can be used within a diagram (local effect) or globally via !define. Some settings apply to specific elements (sequenceMessageAlign, responseMessageBelowArrow). The skinparam page notes that it is gradually being replaced by style.
The <style> tag defines detailed rules. Example for a sequence diagram:
<style>
sequenceDiagram {
LifeLineBorderColor darkgray
LifeLineBackgroundColor #f8f8f8
MessageFontColor #333333
}
</style>Custom classes can be defined:
<style>
.important {
BackgroundColor pink
FontColor darkred
FontWeight bold
}
</style>
participant Alice <<important>>Styles can target specific elements of a type (for example participant inside a sequenceDiagram). Dynamic selectors such as :nth-child(2) or :depth(3) apply different colours depending on depth (useful in WBS). Style provides fine‑grained control and the ability to import themes (e.g. !theme mars).
Diagrams use fonts available on the machine. Properties FontName, FontSize, FontColor modify fonts. OpenIconic or FontAwesome icons are inserted via <&iconName> or through the awslib/font-awesome libraries. Custom sprites can be defined with sprite $name widthxheight <image-data> and used in labels as <$name>.
- Declare elements explicitly: use
participant,class,entity, etc. for clarity and style control. - Structure the diagram: use
package,frameorboxto group related elements. Legends (legend) and titles (title) aid comprehension. - Keep text concise: avoid long sentences; use short labels and add notes for details.
- Choose consistent colours: use CSS styles or themes to harmonise colours. Avoid overly saturated colours; prefer soft palettes (e.g.
theme marsortheme sage). - Test different orientations: the
left to right directionortop to bottom directiondirectives adapt the presentation depending on the number of elements. - Use the preprocessor to factorise: create functions and procedures to avoid duplication and update multiple diagrams easily.
- Mix diagrams: PlantUML allows embedding sub‑diagrams (e.g. a Salt panel inside an activity diagram) to make modelling more realistic.
- Validate syntax: many errors stem from missing parentheses or braces. Use an editor with syntax highlighting or the online PlantUML server to validate diagrams.
- Respect semantics: UML diagrams describe structure and behaviour, not implementation. Avoid overloading a diagram with code details and prefer multiple diagrams for different views.
This documentation covers most PlantUML features needed to generate clear and professional diagrams. For advanced use cases (C4 model, advanced wireframes, specific macros, etc.), consult the official documentation or third‑party libraries. By combining PlantUML syntax, the CSS style mechanism and the preprocessor, you can automate diagram generation for complex projects.