Improving Technical Documentation with Mermaid Diagrams

5 min read Original article ↗

If you've ever tried to explain a microservices architecture using only words, you know the feeling: a wall of text that nobody reads, a whiteboard photo that's blurry and lost in Slack, or a Visio file that only opens on one machine in the office. Mermaid solves this by letting you write diagrams as code — plain text that lives in your repo, diffs cleanly in pull requests, and renders directly in GitHub, GitLab, Notion, and most modern documentation tools.

This post walks through five diagram types that are genuinely useful when documenting real applications, with working examples you can drop into your own docs today.


Why diagrams-as-code matter

The classic problem with architecture diagrams is that they rot. Someone updates the service, forgets to touch the PNG in Confluence, and six months later new engineers are onboarding from a picture that describes a system that no longer exists.

When your diagram lives as a Mermaid code block in the same Markdown file as your ADR or README, it gets updated in the same commit as the code. It's version-controlled, reviewable, and searchable. That's the core value proposition.


1. System context: C4 Component diagram

Before diving into internals, give readers a bird's-eye view of how your system fits into its environment — what users interact with it, what external systems it calls, and what it absolutely does not own.

[Diagram]

This diagram answers the first question every new engineer asks: what does this thing talk to? It takes five minutes to write and saves hours of "wait, do we own the email sending or does the ERP do that?" conversations.


2. Service interactions: Sequence diagram

Once you've established what services exist, sequence diagrams are the most effective way to document how they talk to each other during a specific flow. They force you to be explicit about who initiates what, what's synchronous vs asynchronous, and where failures can occur.

[Diagram]

The autonumber keyword adds step numbers automatically — useful when you reference specific steps in accompanying prose ("step 4 is where the reservation lock is acquired; it expires after 15 minutes").


3. Data model: Entity-Relationship diagram

ER diagrams in Mermaid are compact and readable, making them ideal for README files and wiki pages where you want developers to quickly understand table relationships without opening a database client.

[Diagram]

One practical tip: keep this diagram in sync with your migration files. A simple CI lint step that diffs the schema against a generated ERD catches drift early.


4. State machine: Statediagram

Order status, payment state, subscription lifecycle — any entity with a lifecycle is a candidate for a state diagram. These are often the most underappreciated diagrams in a codebase, yet they answer the question developers ask most frequently: what states can this thing be in, and what transitions are valid?

[Diagram]

This kind of diagram belongs in the same directory as the model it describes — ideally named order-lifecycle.md and linked from the model's docblock. When a developer adds a new status value, the diagram review in the PR becomes the conversation about whether the transition is intentional.


5. Deployment topology: Flowchart

For infrastructure and deployment documentation, flowcharts with subgraphs are the right tool. They're flexible enough to show VPCs, availability zones, load balancers, and data stores in a single readable picture.

[Diagram]

Subgraphs handle the nesting you need to express network boundaries. This diagram communicates which components are in public vs private subnets, what scales horizontally, and what the traffic flow looks like — all without leaving Markdown.


Practical advice for keeping diagrams alive

Put diagrams next to what they describe. An ER diagram in docs/data-model.md gets forgotten. The same diagram in src/models/README.md is read by every engineer who opens that directory.

Use diagram reviews as design reviews. When a PR adds a new service interaction, requiring a sequence diagram update in the same PR turns diagram maintenance into a forcing function for design discussion — not an afterthought.

Don't diagram everything. A CRUD endpoint doesn't need a sequence diagram. Reserve them for flows that are non-obvious, involve multiple services, or have failure modes worth documenting explicitly.

Validate in CI. The @mermaid-js/mermaid-cli package (mmdc) can render diagrams headlessly in CI. A job that fails on malformed Mermaid syntax catches broken diagrams before they reach the docs site.

npx @mermaid-js/mermaid-cli -i architecture.md -o /dev/null

Mermaid won't replace every diagram — sometimes a hand-drawn whiteboard sketch or a carefully laid-out architecture diagram in Figma is the right tool. But for living documentation that travels with your code, renders everywhere, and gets updated by the same engineers who update the system, it's hard to beat.

Start with the sequence diagram for your most complex flow, get it merged into the README, and see how quickly it becomes the first thing new team members reach for.