PlantUML: Powerful Diagrams with Code

Derek ArmstrongDerek Armstrong
8 min read

Imagine trying to design a complex software system without any diagrams. It would be like navigating a maze without a map—confusing and inefficient. In software development, clarity is crucial, and that's where diagramming comes into play. But not just any diagrams—the kind that combine simplicity with the elegance of text, allowing you to design entire systems with just your keyboard. Enter PlantUML: the ultimate tool for diagramming.

In this post, we'll delve into PlantUML, a powerful tool that turns plain text into dynamic diagrams. We'll explore how it works, its numerous benefits, and why it deserves a spot in your development toolkit. So grab your keyboard, and join us on this journey to discover how PlantUML can revolutionize your approach to documentation.

What is PlantUML?

PlantUML is a text-based diagramming tool that lets you generate diagrams from simple text descriptions. Created by Arnaud Roques in 2009, it has grown to become one of the most popular tools for creating visual representations in software development. PlantUML supports a wide variety of diagram types and can be seamlessly integrated into your existing development workflow.

How PlantUML Works

PlantUML uses an intuitive text syntax to describe diagrams, turning written descriptions into graphical representations instantly. For example, here's how you would create a simple sequence diagram:

@startuml
Alice -> Bob: Hello Bob, how are you?
Bob --> Alice: I am good thanks!
@enduml

PlantUML diagram

With just a few lines, PlantUML generates a clear diagram showing the interaction between Alice and Bob. This text-based approach ensures that you can focus on the content of your diagram rather than fiddling with a graphical interface.

Supported Diagram Types

PlantUML supports a wide range of diagram types, making it highly versatile:

  • Sequence Diagrams: Show interactions between objects over time.

  • Class Diagrams: Model the static structure of a system.

  • Component Diagrams: Visualize the organization and dependencies of software components.

  • State Diagrams: Model the different states and transitions of an object.

  • Activity Diagrams: Represent workflows and processes.

  • Entity-Relationship Diagrams: Useful for designing and debugging database schemas.

This flexibility makes PlantUML a one-stop solution for most of your diagramming needs in software development.

Why Choose PlantUML?

PlantUML stands out for its simplicity, versatility, and the ability to integrate seamlessly into your development process. Let’s explore its key advantages:

Simplicity and Ease of Use

PlantUML is text-based, which means you don’t need to wrestle with graphical interfaces. You write what you want, and it creates the diagram for you. This makes it accessible for developers who prefer writing code over fiddling with design tools. Its syntax is intuitive, making the learning curve extremely gentle.

Version Control Compatibility

Because PlantUML diagrams are written as text, they can be easily version-controlled. This means you can track changes, roll back to previous versions, and even merge diagram updates—just as you do with code. This tight integration with version control systems such as Git ensures that your diagrams remain up to date and synchronized with your codebase.

Integration with IDEs and CI/CD

PlantUML plays well with popular integrated development environments (IDEs). Plugins are available for IntelliJ IDEA, Visual Studio Code, and Eclipse, allowing you to generate and preview diagrams directly within your coding environment. PlantUML can also be automated as part of your CI/CD pipeline, ensuring that diagrams are regenerated whenever there are changes in your code.

Automation and Customization

With PlantUML, you can automate the creation of diagrams directly from code or configuration files, saving time and ensuring that your documentation is always up to date. You can also customize diagrams to match your project’s style by adjusting colors, layouts, and fonts, making your diagrams not only functional but also visually appealing.


A Quick Comparison with Other Tools

While there are several diagramming tools out there, PlantUML offers a distinct set of advantages when compared to others:

ToolProsCons
LucidchartEasy to use, cloud-based, collaborativeSubscription model, requires internet
Visual ParadigmFeature-rich, powerful modeling toolsComplex UI, overkill for simple diagrams
Microsoft VisioMature, widely usedCan feel outdated, poor version control
Draw.ioFree, browser-based, collaborativeManual updates can be cumbersome

Unlike these tools, PlantUML integrates directly into the developer workflow, supports automation, and doesn’t require you to use a graphical interface, making it faster and more efficient for agile development environments.


Best Practices for Using PlantUML

Here are a few tips for getting the most out of PlantUML:

Write Clear and Concise Code

Keep your diagram code readable and straightforward. Avoid overly complex diagrams by breaking them down into smaller, modular components. This will make your diagrams easier to maintain and update over time.

Leverage PlantUML’s Advanced Features

Use annotations, notes, and color coding to enhance the clarity of your diagrams. You can also use the !include feature to break large diagrams into smaller, reusable pieces, making your PlantUML files more maintainable.

Version Control Your Diagrams

Store your diagrams alongside your code in a version control system like Git. This ensures that your diagrams evolve with your project and are always in sync with your codebase.

Focus on Readability

While it can be tempting to include every little detail, focus on communicating the key ideas. Keep diagrams simple and focused on the most important information, using multiple diagrams for different aspects of your system if necessary.

Here’s an example of a well-structured PlantUML diagram that groups related elements for clarity:

@startuml
package "Frontend" {
  [Login Page] --> [Dashboard]
  [Dashboard] --> [Profile Page]
}

package "Backend" {
  [API Gateway] --> [Authentication Service]
  [API Gateway] --> [Data Service]
}

[Login Page] -> [API Gateway]
@enduml

PlantUML diagram

This diagram clearly separates frontend and backend components, making it easy to understand how the system is structured without being cluttered.


Examples

In this section, we'll look at various examples of diagrams created using PlantUML. Each example demonstrates a different type of diagram, showcasing the versatility and power of PlantUML.

Sequence Diagram

@startuml
autonumber

actor User as user
participant "Browser UI" as browser
participant "Reseller UI" as reseller_ui

user -> browser : Visit the Reseller UI login page
browser -> reseller_ui : Retrieve the Reseller UI login page
browser <- reseller_ui : Return the login page with form field \nusername, password, and One Time Password(OTP)
user <- browser : Display the page, wait for user input
user -> user: Recall username and password \nfrom memory
user -> browser : Fill in the username and password field
user -> user: Open Google Authenticator, \nread the OTP
user -> browser : Fill in the OTP, and hit the send button
browser -> reseller_ui : Send the username, password and OTP
reseller_ui -> reseller_ui : Verify the information is valid
alt Login valid
    browser <- reseller_ui : Return the logged in page
    user <- browser : Display the logged in page
else Login invalid
    browser <- reseller_ui : Return login failure page
    user <- browser : Display the login failure page
end
@enduml

PlantUML diagram

Class Diagram

@startuml
hide circles

Magic : numberActiveSpells : integer
Magic : totalManaCostPerTurn : integer

Magic <|-- Spells

Spells : spellNumber[]: integer
Spells : powerLevel: integer
Spells : mannaPerTurn: bool
Spells : mannaPerTarget: bool
Spells : castSpell()

Magic <|-- CounterSpells

CounterSpells : spellNumber[]: integer
CounterSpells : powerLevel: integer
CounterSpells : castCounterSpell()

Magic <|-- MagicSupport

MagicSupport : mannaExpending: integer
MagicSupport : powerLevel: integer
MagicSupport : expendManna()
MagicSupport : getPowerLevel()

@enduml

PlantUML diagram

Use Case Diagram

@startuml
skinparam packageStyle rect
(Start) <|-- :Player_1:
Player_1 <|-right- :Player_2:

(GamePlay) <-right-(Start)
(Movement) <-- (GamePlay)
(Move) <-- (Movement)
Note top of (Move): Player moves in given direction

(Combat) <-- (GamePlay)
Rectangle {
  (Attack) <-- Combat
  (Defend) <-- Combat
}

usecase (Access Menus) as Menus 
Menus <-- (GamePlay)

(Upgrades) <-- Menus
Rectangle {
  (Purchase) <-- Upgrades
  (Utilize) <-- Upgrades 
}

(Inventory) <-- Menus
Rectangle {
  (Use Item) <-- Inventory
  (Drop Item) <-- Inventory
  (Info) <-- Inventory
}
Note right of Info: Short description of item

(Purchasing) <-- Menus
Rectangle {
  (Spend) <-- (Purchasing)
  (Receive) <-- (Purchasing)
}

(Purchasing) <-- Purchase


@enduml

PlantUML diagram

Activity Diagram

@startuml

start

:Open and Read Layout Configuration XML;

repeat
  :**Read Process**;
  repeat
  :**Read Thread**;
  note: at least one should be there, the main thread
    repeat
      :**Read Component**;
      repeat
        : **Read Interface**;
      repeat while(interfaces?)
      : **Generate Interfaces Code**;
    repeat while(components?)
  : **Generate Components Code**;
  repeat while(threads?)
  : **Generate Threads Code**;
repeat while(processes?)
:**Generate Processes Code**;

stop

@enduml

PlantUML diagram

Component Diagram

@startuml
skinparam backgroundcolor transparent

node Backend
database Database
node Frontend
component Collectd
agent Client1
agent Client2
agent Client3
agent Client4

Frontend -- Backend

Backend -- Database
Backend -- Collectd

Collectd .. Client1
Collectd .. Client2
Collectd .. Client3
Collectd .. Client4

@enduml

PlantUML diagram

State Diagram

@startuml

title performing I/O

[*] --> Client
Client: Process uri in Client

Client -> Server : uri-data
state Server {
  [*] -> monitor
  monitor: Server starts monitoring
  monitor: Stops at end of Server life
}

Client -> Database: Client
Database: database operations

state runcommand {
  Database -> command: Database
  command -> find: query
  command: send command to server

  monitor -> select: server-data

  find --> select
  select: select process to find proper server
  select --> find: Server

  find --> query: server
  query: encodes query and send to server
  query: decodes result
  query --> find: result

}

find -> Cursor: cursor-data
Cursor: stores docs
Cursor: retrieves new docs

Cursor -> fetch: document
fetch --> getmore
getmore: encodes query and send to server
getmore: decodes result
getmore --> fetch: new-documents


fetch -> [*]
@enduml

PlantUML diagram

Conclusion

Diagrams are crucial for communicating software architecture and workflows, and PlantUML makes creating them simple, quick, and collaborative. By turning text into diagrams, it integrates seamlessly into a developer's workflow, ensuring that your documentation is always clear, up to date, and easy to version control.

If you’re looking for a tool that bridges the gap between code and design, PlantUML is the perfect choice. Start using it today and let your diagrams evolve alongside your codebase with the simplicity of plain text.

0
Subscribe to my newsletter

Read articles from Derek Armstrong directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Derek Armstrong
Derek Armstrong

I share my thoughts on software development and systems engineering, along with practical soft skills and friendly advice. My goal is to inspire others, spark ideas, and discover new passions.