Have you ever felt that writing design documents takes too long, or that updating a diagram means going through the tedious cycle of re-exporting images and re-uploading them? I used to spend a huge amount of time creating diagrams in PowerPoint or Excel, exporting them as images, and pasting them into wikis. On one project, fixing a single sequence diagram meant opening PowerPoint, adjusting shapes, exporting the image, and re-uploading it to the wiki — a process that easily took over 15 minutes, all for three lines of actual changes. That frustration pushed me to look for a better way. In this article, I'll show you how to draw UML diagrams directly in VSCode's Markdown preview.
Why Draw UML Diagrams in Markdown?
Writing design documents and specs is an unavoidable part of software development. But introducing a dedicated UML tool brings its own headaches: licensing costs, and the challenge of rolling it out to every team member.
The biggest advantage of text-based UML is that your diagrams live in version control alongside your code. You can track changes with Git, include diagrams in code reviews, and keep documentation in sync with the codebase. IPA's "DX White Paper 2023" also highlights that unified management of documentation and code contributes to development efficiency — and this approach is a direct application of that principle.
Concrete Benefits of Text-Based Diagram Management
Let's break down the practical benefits of managing UML diagrams as text.
Visualizing diffs becomes effortless. With image files, it's nearly impossible to see at a glance what changed. With text, Git diffs and pull request reviews show exactly which lines changed. On our projects, design reviews improved noticeably — reviewers started asking precise questions like "Why did the direction of this arrow change?" rather than vaguely comparing two images.
Searchability is a major win. If you want to find every diagram that mentions a particular class, a simple grep across the repository does the job instantly. With image-based diagrams, that kind of cross-cutting search is essentially impossible.
Diagrams are less likely to go stale. Image files stored separately from code are easy to forget when updating logic. When diagrams are embedded as text in Markdown files, updating them becomes a natural part of the pull request workflow — reviewed and updated alongside the code changes.
I'll be honest: the idea of "drawing diagrams in text" didn't immediately click for me. But once I started using it, I realized how much the low barrier to editing encouraged me to actually keep diagrams up to date.
Getting Started with Mermaid — the Easiest Path
My first recommendation is Mermaid. All you need is the VSCode extension "Markdown Preview Mermaid Support," and you can start drawing diagrams immediately.
Installation
Setup is simple. Open the Extensions panel (Ctrl+Shift+X / Cmd+Shift+X), search for "Markdown Preview Mermaid Support," and install it. There are no external dependencies like Java or Docker — the extension works on its own, which also makes it easy to roll out to your whole team. Once installed, write a ```mermaid block in any Markdown file, and it will render in the preview pane (Ctrl+Shift+V / Cmd+Shift+V).
Diagram Types and Syntax
Mermaid's syntax is refreshingly simple. Here's a flowchart representing a business workflow:
graph TD
A[Receive Inquiry] --> B{Review Content}
B -->|Technical Consultation| C[Assign to Engineer]
B -->|Quote Request| D[Assign to Sales]
C --> E[Conduct Interview]
D --> E
E --> F[Create Proposal]TD in graph TD stands for "Top to Down." Change it to LR (Left to Right) for a horizontal layout. Node shapes are controlled by brackets: [ ] for rectangles, { } for diamonds (conditionals), and (( )) for circles.
Sequence diagrams are equally intuitive and great for visualizing API calls and system interactions:
sequenceDiagram
participant U as User
participant F as Frontend
participant A as API Server
participant D as Database
U->>F: Login Request
F->>A: Call Auth API
A->>D: Query User Info
D-->>A: Auth Result
A-->>F: Issue Token
F-->>U: Login CompleteFor planning and requirements phases, Gantt charts are a great fit:
gantt
title Project Schedule
dateFormat YYYY-MM-DD
section Requirements
Interviews :a1, 2025-04-01, 10d
Write Spec :a2, after a1, 7d
section Design
High-level Design :b1, after a2, 14d
Detailed Design :b2, after b1, 10d
section Development
Implementation :c1, after b2, 30dMermaid also supports ER diagrams (erDiagram), state diagrams (stateDiagram-v2), pie charts (pie), and more — with new diagram types added regularly. Start with flowcharts and sequence diagrams, then explore from there.
Common Pitfalls with Mermaid
The first stumbling blocks I hit were indentation rules and arrow syntax — the difference between --> and -->> takes a little getting used to. That said, the official docs are thorough, and the learning curve is gentle.
One specific issue I ran into: using Japanese full-width parentheses () in node labels caused parse errors. Since Mermaid treats certain punctuation as syntax, it's safest to wrap labels containing special characters in double quotes. Knowing these small gotchas in advance saves a lot of frustration early on.
For large diagrams that don't fit on one screen, try graph LR for a horizontal layout, or use subgraph blocks to group related nodes — both help keep complex diagrams readable.
Going Further with PlantUML
For more complex UML needs, PlantUML is a powerful option. It supports the full breadth of UML 2.0, including class diagrams, ER diagrams, and state machine diagrams.
To use it in VSCode, install the "PlantUML" extension and configure either a local Java runtime or a PlantUML server. When deciding between Mermaid and PlantUML, I found the most practical answer is: use both, depending on the situation.
Quick flowcharts and sequence diagrams → Mermaid. Detailed class designs and ER diagrams → PlantUML. That division has worked well for our team.
Setting Up PlantUML
PlantUML requires a bit more setup than Mermaid:
- Install a Java runtime: PlantUML runs on Java, so you'll need a JDK or JRE. Skip this if you already have a Java dev environment.
- Install the "PlantUML" VSCode extension: Search for it in the Extensions panel and install.
- Choose a rendering method: You can use a local Java runtime or a shared PlantUML server. A shared server is great for teams — it removes the dependency on each member's local environment and eliminates environment-related inconsistencies.
If you're using Docker, spinning up a PlantUML server is straightforward: docker run -d -p 8080:8080 plantuml/plantuml-server:jetty. Then point the plantuml.server setting in VSCode to that URL.
PlantUML Syntax Examples
Here's a class diagram in PlantUML:
@startuml
class User {
- id: String
- name: String
- email: String
+ login(): Boolean
+ updateProfile(): void
}
class Order {
- orderId: String
- amount: Decimal
+ calculate(): Decimal
}
User "1" -- "*" Order : places
@endumlAccess modifiers use + (public), - (private), and # (protected), making class intent clear at a glance. Relationships between classes — associations, aggregations, compositions, inheritance — follow standard UML notation, making PlantUML well-suited for detailed design phases.
Activity diagrams are another highlight for real-world use, especially for modeling business processes with branching and parallel flows:
@startuml
start
:Receive Order;
if (In Stock?) then (yes)
:Process Shipment;
:Arrange Delivery;
else (no)
:Notify: Awaiting Stock;
:Place Order with Supplier;
endif
:Notify Customer of Status;
stop
@endumlThe initial setup takes some effort, but once the environment is in place, the whole team can produce consistent, high-quality diagrams efficiently.
Choosing Between Mermaid and PlantUML
After working with both tools, here's a practical comparison to help you decide:
| Criteria | Mermaid | PlantUML |
|---|---|---|
| Setup effort | Extension only, works immediately | Requires Java or a server |
| Flowcharts | Simple and easy to write | Equally supported |
| Sequence diagrams | Sufficient for most use cases | Supports advanced expressions (conditionals, loops, etc.) |
| Class diagrams | Basic support | Full access modifiers and relationship types |
| ER diagrams | Supported (erDiagram) | Supported (more customization options) |
| GitHub/GitLab integration | GitHub renders Mermaid natively in previews | Requires a separate image generation step |
| Theming and styling | CSS-based customization | Fine-grained control via skin parameters |
A notable advantage for Mermaid: GitHub natively renders Mermaid blocks in READMEs, issues, and pull request descriptions — no extra configuration needed. For GitHub-centric workflows, this is a significant convenience.
That said, if you need strict UML compliance or are drawing large, complex class diagrams, PlantUML's expressiveness may be necessary. My recommended approach: start with Mermaid, and move to PlantUML when you hit its limits.
Team Workflows and Practical Tips
When standardizing on Markdown and text-based UML across a team, a few operational considerations matter.
Establish Documentation Standards
Start by documenting your conventions in the project README or a docs/ directory. Agreeing on "which tool for which diagram type" prevents a mix of inconsistent syntax from creeping in. In my experience, written conventions start paying off noticeably once a team grows beyond five people.
Useful items to include in your conventions:
- Tool per diagram type: e.g., flowcharts and sequence diagrams → Mermaid; class diagrams and ER diagrams → PlantUML
- File organization: centralize all diagram Markdown under
docs/diagrams/, or co-locate them with the relevant feature directory - Naming conventions: include the diagram type and subject in filenames, e.g.,
seq-login-flow.md,class-user-domain.md
These conventions don't need to be perfect from day one — treat them as living documents that grow with the team. Start minimal and add rules when someone raises a pain point.
Quality Checks in CI/CD
Integrating diagram rendering checks into your CI/CD pipeline is also worth considering. Catching syntax errors before they reach the main branch keeps documentation quality consistent. A growing number of teams are automating validation using Mermaid CLI and PlantUML command-line tools in GitHub Actions or GitLab CI.
For example, with GitHub Actions you can use Mermaid CLI's mmdc command to verify that all Mermaid blocks in Markdown files render without errors. If a diagram has a syntax error, the CI job fails — preventing broken diagrams from ever landing in the main branch. The initial setup takes a bit of time, but the long-term payoff of never discovering silent, broken diagrams is well worth it.
Share Recommended Extensions
One often-overlooked step: share your VSCode extension configuration. Add recommended extensions to .vscode/extensions.json so new team members are prompted to install them automatically when they open the project. Looking back, skipping this early on meant I answered the same setup questions repeatedly during onboarding — a completely avoidable overhead.
Here's a minimal extensions.json to get started:
{
"recommendations": [
"bierner.markdown-mermaid",
"jebbs.plantuml"
]
}When someone opens the project in VSCode, they'll see a prompt asking if they want to install the recommended extensions — a small touch that meaningfully speeds up onboarding.
Common Questions When Rolling This Out
When introducing this approach to a team, a few questions tend to come up. Here are the most common ones and how I'd address them.
"Can non-engineers use this?"
For basic Mermaid flowcharts, yes — absolutely. The syntax is simple enough that no programming background is required; it maps naturally to the mental model of "boxes and arrows." On one of our projects, a director drafted business flow outlines in Mermaid, which engineers then reviewed. There was an initial learning curve, but after writing a few diagrams, it became second nature.
"How much can we customize the look?"
Mermaid supports CSS-based theming — you can change colors and fonts, and use init directives at the top of a Markdown file to set theme colors. PlantUML offers even more control via skinparam, letting you fine-tune line colors, backgrounds, font sizes, and more. That said, I'd caution against over-investing in visual polish — the real value of text-based diagrams is clarity and ease of maintenance, not pixel-perfect aesthetics.
"How do we migrate existing diagrams?"
If you have a large library of diagrams in PowerPoint or Visio, migrating everything at once isn't realistic. The approach I recommend: switch to text-based diagrams for all new work, and migrate existing ones incrementally as they need to be updated. Trying to migrate everything in one go often turns the migration itself into a bottleneck. Prioritize high-churn diagrams first — that's where you'll see the highest return on the investment.
Conclusion: Better Documentation Accelerates the Entire Development Cycle
Drawing UML diagrams in VSCode's Markdown preview is a practical, no-cost approach to dramatically improving how your team creates and maintains design documents. Start with Mermaid for quick wins, add PlantUML as your needs grow, and let the two tools complement each other.
The benefits go well beyond "faster diagram creation." Text-based diagrams unlock version-controlled change tracking, integration with code review workflows, and automated quality checks via CI/CD — applying software development best practices to documentation itself. That's where the real, lasting value lies.
Balancing documentation quality with development speed is a challenge that directly affects a company's competitive edge. At aduce, we provide technical consulting — from development process optimization to system design — tailored to each client's needs. If you're struggling with documentation management or development efficiency, feel free to reach out to aduce.
