Drawing UML diagrams with a mouse is slow, tedious, and nearly impossible to keep in sync with your actual codebase. Every time a class changes or a new endpoint gets added, someone has to manually update the diagram or more realistically, nobody does, and the diagram becomes outdated within a week. That's exactly why more developers are learning how to create UML diagrams using code instead. With a text-based approach, your diagrams live right next to your source code, get version-controlled alongside it, and update in seconds.
This article covers the practical steps for generating UML diagrams from plain text code, the tools that make it possible, and the mistakes that trip people up when they start.
What does it mean to create UML diagrams using code?
Creating UML diagrams using code often called "diagram as code" means writing plain text descriptions that a tool renders into visual diagrams. Instead of dragging boxes and arrows on a canvas, you write short, readable markup that describes your classes, sequences, use cases, or component relationships.
For example, a simple class diagram in PlantUML looks like this:
Example markup:
@startuml
class User {
-name: String
-email: String
+login(): void
}
class Order {
-orderId: int
-total: float
+placeOrder(): void
}
User "1" -- "" Order
@enduml
That short block of text produces a full UML class diagram with two classes, their attributes, methods, and a one-to-many relationship. No clicking, no aligning, no cleanup.
This approach covers every major UML diagram type: class diagrams, sequence diagrams, activity diagrams, use case diagrams, state diagrams, component diagrams, and more.
Why would a developer write diagrams in code instead of using a visual editor?
There are several practical reasons this approach has gained traction among software engineers:
- Version control. Diagram files are plain text, so they fit naturally into Git. You can track changes, review diagram updates in pull requests, and roll back if needed. If you've ever wondered how diagram-as-code tools compare to traditional drag-and-drop editors, the version control difference alone is significant.
- Speed of updates. Changing a class name or adding a method means editing one line of text, not redrawing boxes and realigning arrows.
- Consistency. The rendering engine handles layout, spacing, and styling automatically. No more diagrams where one box is slightly misaligned.
- Automation. You can generate diagrams from codebases, database schemas, or API definitions using scripts. This is especially useful in CI/CD pipelines where documentation needs to stay current.
- Collaboration. Because the source is text, teammates can comment on, suggest changes to, or fix diagrams using the same code review workflows they already use.
For a deeper breakdown of how these tools stack up against visual editors, this comparison of diagram-as-code and drag-and-drop tools covers the tradeoffs in detail.
What tools can I use to create UML diagrams from code?
Several well-established tools support text-based UML diagramming. Each has different strengths depending on your workflow:
PlantUML
PlantUML is the most widely used diagram-as-code tool. It supports all standard UML diagram types plus non-UML diagrams like Gantt charts and mind maps. You write diagrams in its own concise markup language, and it renders to PNG, SVG, or PDF. It integrates with most IDEs, documentation platforms, and CI tools.
Mermaid
Mermaid is a JavaScript-based diagramming tool that renders directly in Markdown files and web pages. GitHub, GitLab, and many documentation platforms support Mermaid natively meaning you can embed a diagram in a README and it renders without any plugin. It covers class diagrams, sequence diagrams, flowcharts, and more.
Structurizr DSL
Structurizr uses a domain-specific language designed for the C4 model of software architecture. If your primary goal is documenting system architecture at different zoom levels (context, container, component, code), Structurizr is purpose-built for that.
D2
D2 is a newer, general-purpose diagram scripting language that emphasizes readability and modern styling. It handles UML-style diagrams but also supports network diagrams, ER diagrams, and custom shapes.
If you want a detailed tool-by-tool breakdown, this guide on the best diagram-as-code tools for software engineers compares features, syntax, and integrations.
How do I create a UML class diagram using PlantUML?
Here's a step-by-step walkthrough for one of the most common UML diagram types:
- Install or access PlantUML. You can use the PlantUML online server to try it immediately, or install it locally via a plugin for VS Code, IntelliJ, or other editors.
- Define your classes. Start with
@startumland end with@enduml. Between those markers, define each class with its attributes and methods. - Declare relationships. Use arrows to show inheritance (
<|--), composition (--), aggregation (o--), or association (--). You can label relationships and specify cardinality. - Add styling (optional). PlantUML lets you change colors, fonts, and layouts using skinparam commands or themes.
- Render the diagram. Save the file with a
.pumlextension and render it through your IDE plugin, the online server, or the command line.
Example with relationships:
@startuml
abstract class PaymentMethod {
+processPayment(amount: float): boolean
}
class CreditCard {
-cardNumber: String
+processPayment(amount: float): boolean
}
class PayPal {
-email: String
+processPayment(amount: float): boolean
}
PaymentMethod <|-- CreditCard
PaymentMethod <|-- PayPal
class ShoppingCart {
-items: List<Item>
+checkout(payment: PaymentMethod): void
}
ShoppingCart ..> PaymentMethod : uses
@enduml
This produces a clean class diagram showing inheritance from an abstract class and a dependency from ShoppingCart to PaymentMethod. No manual layout needed.
How do I create a UML sequence diagram using code?
Sequence diagrams show how objects interact over time perfect for documenting API calls, authentication flows, or message passing between services. Here's how to write one in PlantUML:
@startuml
actor User
participant "Frontend" as FE
participant "API Gateway" as GW
participant "Auth Service" as Auth
database "Database" as DB
User -> FE : Enter credentials
FE -> GW : POST /login
GW -> Auth : Validate credentials
Auth -> DB : Query user
DB --> Auth : User record
Auth --> GW : JWT token
GW --> FE : 200 OK + token
FE --> User : Dashboard
@enduml
Mermaid handles sequence diagrams with a slightly different syntax:
sequenceDiagram
participant Client
participant Server
participant Database
Client->>Server: POST /api/login
Server->>Database: SELECT user
Database-->>Server: user data
Server-->>Client: 200 OK (JWT)
Both approaches produce a clear, layout-optimized sequence diagram from a few lines of text.
Can I generate UML diagrams automatically from existing code?
Yes, and this is where the approach becomes especially powerful for large codebases.
Several tools and plugins can parse your source code and generate UML diagrams from it:
- PlantUML + Doxygen: Doxygen can extract class information from C++, Java, Python, and other languages and feed it to PlantUML for rendering.
- VS Code extensions: Extensions like "PlantUML" and "Draw.io Integration" can generate class diagrams directly from your open project.
- IntelliJ IDEA: IntelliJ's built-in diagram feature can generate class diagrams from Java/Kotlin code and export them to PlantUML format.
- Python-specific tools: Libraries like
pyreverse(part of Pylint) generate UML class diagrams from Python packages directly. - API-to-diagram scripts: You can write scripts that parse OpenAPI/Swagger specs and output sequence or component diagrams in Mermaid or PlantUML format.
These generated diagrams can live in your repo and get regenerated on each build, so your architecture documentation never drifts out of date.
What are common mistakes when creating UML diagrams with code?
Even though text-based diagramming is straightforward, a few patterns trip people up:
- Trying to fit everything into one diagram. A single class diagram with 50 classes is unreadable whether it's drawn by hand or generated from code. Split large systems into focused, smaller diagrams one per module or bounded context.
- Ignoring diagram type selection. Using a class diagram when a component diagram would communicate the idea more clearly is a common mistake. Pick the UML diagram type that matches what you're trying to communicate.
- Not pinning tool versions. If your CI pipeline renders diagrams, pin the PlantUML or Mermaid version. Rendering behavior can change between versions, which might break layout or introduce visual differences.
- Over-styling. Custom colors, fonts, and skins are tempting but can make diagrams inconsistent across a team. Agree on a style and stick to it.
- Skipping relationship labels. Unlabeled arrows leave readers guessing about the nature of a relationship. Always label associations, dependencies, and multiplicities.
- No documentation alongside diagrams. A diagram without context is confusing. Add a brief note explaining what the diagram shows and when it was last updated.
How do I integrate UML diagrams into my documentation workflow?
The real value of code-based diagrams shows up when they become part of your existing documentation and development process:
- Store diagram source files in your repository. Keep
.pumlor.mmdfiles in a/docs/diagramsfolder alongside your code. - Render diagrams in CI. Add a build step that converts diagram source files to images and commits them back or publishes them as build artifacts.
- Embed in documentation platforms. Tools like MkDocs, Docusaurus, and Confluence support Mermaid or PlantUML rendering natively or through plugins.
- Use diagrams in pull request reviews. When proposing architecture changes, include a diagram diff so reviewers can see structural changes visually alongside code changes.
- Link diagrams from code comments. Reference specific diagrams from relevant code files so developers can find architectural context quickly.
What should I try next?
Start small. Pick one diagram you've been meaning to update a class diagram for a core module, or a sequence diagram for your authentication flow and rewrite it in PlantUML or Mermaid. Spend 15 minutes with the PlantUML class diagram reference or the Mermaid class diagram syntax guide, and you'll have a working diagram by the end of the session.
Quick-start checklist:
- Choose a tool: PlantUML for full UML coverage or Mermaid for Markdown-native rendering
- Write one diagram start with a class diagram or sequence diagram for a feature you know well
- Render it using the online editor to verify the output
- Save the source file in your project's
/docsdirectory - Add it to your README or internal documentation
- Set up a VS Code or IDE plugin for live preview as you edit
- Share it with your team and gather feedback on readability
Once you've created your first diagram in code, going back to drag-and-drop tools feels unnecessarily slow. The text-based approach scales with your project and keeps your architecture documentation honest.
Diagram as Code vs Drag and Drop Tools Comparison
Diagram Code Generator for Flowcharts – Create Visual Flowcharts Instantly
Best Diagram Code Tools for Software Engineers in 2024
Online Diagram Code Editor with Real-Time Collaboration
How to Read Diagram Codes: Syntax and Notation Guide
Diagram Syntax for Beginners: a Simple Guide to Getting Started