Your Markdown Diagrams Could Look Like This: 12 Mermaid Tricks Worth Copying
Build layered architectures, release pipelines, recovery loops and richer planning diagrams with 12 Mermaid techniques you can copy into Markdown.
A few boxes explain a simple process. They stop being enough when the interesting part is a hand-off, a failure path, a shared dependency or several things happening at once.
The examples below go beyond the starter diagram. Each is a complete, editable model with a different technique to borrow, not the same graph with different labels.
Paste a block into a supporting Markdown viewer and editor, then change one relationship and compare the result.
Compatibility: Mermaid is a renderer feature, not core Markdown. Your app needs to support the diagram type and configuration used. Examples 2, 5 and 8 are shown in Markdific’s dark theme and request Mermaid’s dark theme in the source. Other hosts may restrict configuration or style the result differently. On Medium, upload the diagram image and keep the copyable source beneath it.
1. Build a real hand-off diagram with ownership boundaries
A publishing process crosses people and decisions, not just a row of steps. This example gives research, writing and release their own working areas, with a revision loop inside the final stage.
```mermaid
flowchart LR
subgraph research[Research]
direction TB
collect[Collect sources] --> verify[Verify claims]
verify --> outline[Build outline]
outline --> brief[Ready to write]
end
subgraph author[Author]
direction TB
draft[Write draft] --> demo[Build examples]
demo --> images[Capture diagrams]
images --> edit[Edit package]
end
subgraph editor[Editor]
direction TB
check{Approved?} -->|Yes| publish[Publish]
check -->|No| revise[Request changes]
revise --> check
publish --> archive[(Source archive)]
publish --> inspect[Check live page]
end
research --> author --> editor
classDef work fill:#dff4fb,stroke:#2086a7,color:#15324a;
classDef gate fill:#fff1ba,stroke:#bd911d,color:#433211;
classDef change fill:#ffe0cd,stroke:#cf773a,color:#4a2918;
class collect,verify,outline,brief,draft,demo,images,edit,publish,inspect work;
class check gate;
class revise change;
```What to copy: The trick is the combination of named subgraphs, local direction and a clear phase hand-off. The group arrows connect ownership stages; they do not claim that a particular internal task automatically triggers the next group. Keep that distinction explicit when documenting a real process.
Connect the group IDs when the hand-off is between phases. Cross-group links to internal nodes can cause a subgraph to inherit the parent direction, so check the result rather than treating local direction as a positioning command.
For syntax details, see the flowchart reference.
2. Layer an architecture instead of drawing a spaghetti graph
A useful architecture picture distinguishes entry points, services and stored information. Here, three clients share a gateway, then split into document-ingestion and search paths.
```mermaid
%%{init: {"theme":"dark","flowchart":{"nodeSpacing":24,"rankSpacing":32}}}%%
flowchart TB
subgraph clients[Clients]
web[Web app]
desktop[Desktop app]
script[Automation]
end
subgraph services[Application services]
gateway[API gateway] --> auth[Access check]
auth --> upload[Import service]
auth --> search[Search service]
jobs[Indexer]
end
subgraph storage[Storage]
files[(Source files)]
queue[(Job queue)]
index[(Search index)]
end
web --> gateway
desktop --> gateway
script --> gateway
upload -->|Store| files
upload -->|Enqueue| queue
queue --> jobs
jobs -->|Update| index
search -->|Query| index
search -. Retrieve .-> files
```What to copy: The trick is to group by responsibility and label the important service-to-data connections. Cylinders distinguish storage from processing, while the queue makes the asynchronous indexing path visible.
The gateway is a genuine shared entry point. Do not draw a separate copy for every client unless those are actually separate components.
I’m building Markdific because I wanted a simpler way to read, edit, preview and export Markdown files, including documents received from AI tools. These examples use its actual preview. The techniques themselves are Mermaid, so you can adapt them in another compatible app too.
3. Show parallel checks and the gate that brings them together
A release pipeline becomes much more informative when it shows concurrent work, the pass condition and the rollback route in the same picture.
```mermaid
flowchart TB
push([Commit]) --> build[Build package]
build --> unit[Unit tests]
build --> integration[Integration tests]
build --> docs[Docs check]
build --> scan[Dependency scan]
unit --> gate{All checks pass?}
integration --> gate
docs --> gate
scan --> gate
gate -->|No| blocked[Block release]
blocked --> fix[Fix and recommit]
gate -->|Yes| staging[Deploy staging]
staging --> smoke[Smoke test]
smoke --> healthy{Healthy?}
healthy -->|Yes| release[Release]
healthy -->|No| rollback[Roll back staging]
rollback --> staging
classDef test fill:#e0e7ff,stroke:#6472bf,color:#202d56;
classDef good fill:#dcfce7,stroke:#328356,color:#16442b;
classDef issue fill:#ffe1d4,stroke:#c76b3a,color:#512d1b;
class unit,integration,docs,scan,smoke test;
class release good;
class blocked,fix,rollback issue;
```What to copy: The trick is fan-out and fan-in: several checks feed one decision instead of pretending that every test happens in sequence. The labels still need a rule in prose: staging begins only after all required checks pass.
The four checks are siblings, not a chain. Fan-in shows their shared decision point; the Yes and No labels keep the release rule visible.
4. Use sequence blocks to reveal cache hits, retries and failures
A single arrow labelled “fetch document” hides a lot. A sequence diagram can show who sends each message, when a cache is used and what happens when the source fails.
```mermaid
sequenceDiagram
autonumber
actor Reader
participant App
participant Cache
participant API
participant Store
Reader->>App: Open document
App->>Cache: Find preview
alt Cached preview exists
Cache-->>App: Preview
else Cache miss
loop Up to two source attempts
App->>API: Request document
API->>Store: Read source
Store-->>API: Source or error
API-->>App: Result
end
alt Source received
App->>App: Render Markdown
App->>Cache: Save preview
else Attempts failed
App->>App: Prepare recovery message
end
end
App-->>Reader: Preview or recovery action
```What to copy: The trick is using alt and loop blocks around real interactions. A cache hit and cache miss are alternatives, not two consecutive operations. The retry label states a limit; it does not implement that policy. Keep participant count small enough that the lifelines remain easy to follow.
Use an outer alternative for the cache and an inner alternative for the eventual fetch result. The bounded retry loop belongs only inside the cache-miss branch.
For syntax details, see the sequence diagram reference.
5. Make a data pipeline show both records and recovery paths
A pipeline that shows only the happy path conceals where rejected records go. This one separates incoming data, validation, persistent stores and the outputs people actually use.
```mermaid
%%{init: {"theme":"dark","flowchart":{"nodeSpacing":24,"rankSpacing":30}}}%%
flowchart TB
csv[CSV upload] --> intake[Receive records]
api[API input] --> intake
intake --> queue[(Input queue)]
queue --> parse[Parse and normalise]
parse --> valid{Valid record?}
valid -->|No| rejected[(Rejected records)]
rejected --> repair[Inspect and repair]
repair --> intake
valid -->|Yes| transform[Transform fields]
transform --> archive[(Original archive)]
transform --> data[(Working dataset)]
data --> index[Build index]
data --> report[Build report]
index --> search[Search results]
report --> dashboard[Dashboard]
archive -. Audit .-> dashboard
```What to copy: The trick is visual grammar: boxes transform information, cylinders store it, and labelled branches explain the rejected-record route. The recovery connection is deliberately visible rather than buried in a footnote.
Follow the No branch all the way back to intake. That return path explains recovery, while the audit link has a different meaning from the main processing arrows.
6. Reuse a visual vocabulary across several outcomes
Styling becomes useful when the same colour means the same kind of work throughout the diagram. Here, automated checks, human decisions and final outcomes each have a consistent treatment.
```mermaid
%%{init: {"flowchart":{"nodeSpacing":20,"rankSpacing":20,"padding":10}}}%%
flowchart TB
request([New request]) --> parse[Read details]
parse --> rules[Run rule checks]
rules --> eligible{Eligible?}
eligible -->|No| reject[Explain rejection]
eligible -->|Yes| risk[Check exceptions]
risk --> normal{Standard case?}
normal -->|Yes| prepare[Prepare result]
normal -->|No| expert[Specialist review]
expert --> approval{Approved?}
approval -->|No| followup[Request more detail]
followup --> expert
approval -->|Yes| prepare
prepare --> complete([Ready to deliver])
reject --> closed([Closed])
classDef automated fill:#dbeafe,stroke:#4775bd,color:#183357;
classDef manual fill:#fef3c7,stroke:#ad8826,color:#443512;
classDef terminal fill:#dcfce7,stroke:#3d8a5b,color:#173e28;
classDef exception fill:#ffedd5,stroke:#bf783a,color:#4e3019;
class parse,rules,risk,prepare automated;
class expert,approval manual;
class complete,closed terminal;
class reject,followup exception;
```What to copy: The trick is classDef plus named class assignments. Change one definition to restyle an entire category. The labels and shapes preserve the meaning without colour, and category names such as manual are less misleading than calling every highlighted node successful.
Notice that Specialist review and Approved? share a category even though one is an action and one is a decision. Colour describes responsibility; shape describes the kind of node.
Try changing one class definition in Markdific and preview how it updates the whole category. Start with this example, then adapt the colours to your own diagram.
7. Separate the main request from supporting signals
Request handling and observability belong in the same system, but they should not look like one long chain of mandatory user-facing steps.
```mermaid
flowchart TB
subgraph request[Request path]
client[Client] --> gateway[Gateway]
gateway --> service[Document service]
service --> cache{Cached?}
cache -->|Yes| response[Build response]
cache -->|No| storage[(Document store)]
storage --> response
response --> reader[Reader]
end
subgraph signals[Supporting signals]
logs[(Request log)] --> trace[Trace view]
metrics[(Metrics)] --> alerts[Alert rules]
events[(Event stream)] --> audit[Audit view]
end
gateway -. Log .-> logs
service -. Measure .-> metrics
response -. Publish event .-> events
alerts -. Notify .-> operator[Operator]
classDef signal fill:#ede9fe,stroke:#8b74bf,color:#382b58;
class logs,trace,metrics,alerts,events,audit signal;
```What to copy: The trick is to reserve solid arrows for the request path and dotted links for logs, metrics and events. The distinction is a convention stated here, not a built-in delivery guarantee. It prevents a logging box from looking like a task every reader must perform after a request.
Get Yugene’s stories in your inbox
Join Medium for free to get updates from this writer.
The arrow convention does the work: solid means request handling, dotted means a supporting signal. Explain that convention whenever readers might otherwise interpret every arrow as the same thing.
8. Nest states to explain what happens inside a lifecycle stage
A document can be “in review” while moving through several internal states. A composite state lets you expand that stage without turning every internal transition into a top-level lifecycle event.
```mermaid
%%{init: {"theme":"dark"}}%%
stateDiagram-v2
direction LR
[*] --> Draft
Draft --> Review: submit
state Review {
direction TB
[*] --> Technical
Technical --> Editorial: checks pass
Technical --> Corrections: changes needed
Corrections --> Technical: resubmit
Editorial --> Ready: approved
Ready --> [*]
}
Review --> Scheduled: review complete
Scheduled --> Live: release
state Live {
direction TB
[*] --> Serving
Serving --> Degraded: errors
Degraded --> Recovering: rollback
Recovering --> Serving: healthy
}
Live --> Archived: retire
Archived --> [*]
```What to copy: The trick is nesting. Review and Live remain recognisable stages, but each contains its own progression and recovery path. Transition labels describe events. Check every route back to a working state, not only the forward route.
Review completion is different from one individual check passing. The composite state keeps those two levels of detail separate.
For syntax details, see the state diagram reference.
9. Put relationship counts in the diagram, not in a legend nobody reads
A diagram of boxes labelled Document, Revision and Tag leaves important questions unanswered. Can a document have several revisions? Can the same tag belong to many documents?
```mermaid
erDiagram
WORKSPACE ||--o{ DOCUMENT : contains
AUTHOR ||--o{ DOCUMENT : writes
DOCUMENT ||--o{ REVISION : has
DOCUMENT ||--o{ DOC_TAG : classified_by
TAG ||--o{ DOC_TAG : used_in
WORKSPACE {
string workspace_id PK
string name
}
AUTHOR {
string author_id PK
string display_name
}
DOCUMENT {
string document_id PK
string workspace_id FK
string author_id FK
string title
}
REVISION {
string revision_id PK
string document_id FK
int version
}
TAG {
string tag_id PK
string label
}
DOC_TAG {
string document_id FK
string tag_id FK
}
```What to copy: The trick is ER cardinality plus a linking entity. DOC_TAG makes the many-to-many relationship explicit rather than drawing an unexplained line between two tables. The keys and counts describe this fictional model.
DOC_TAG represents the join between documents and tags. Read the cardinality at each end before assuming that the connection means one-to-one.
For syntax details, see the ER diagram reference.
10. Show one shared component serving several paths
Copying the same component into several corners makes a diagram look organised while hiding the fact that those paths depend on one shared service.
```mermaid
flowchart TB
notes[Local Markdown] --> load[Read source]
repo[Repository file] --> load
ai[AI-generated file] --> load
load --> validate[Validate assets]
validate --> parser[Parse document]
parser --> renderer[Shared renderer]
assets[(Image folder)] -. Resolve .-> renderer
theme[(Theme settings)] -. Style .-> renderer
renderer --> screen[Screen preview]
renderer --> html[HTML output]
renderer --> pdf[PDF output]
screen --> inspect[Inspect content]
html --> share[Share package]
pdf --> share
inspect --> revise[Revise source]
revise -. Next revision .-> load
classDef shared fill:#dff5f2,stroke:#338a7b,color:#173f39;
classDef output fill:#e0e7ff,stroke:#6b78be,color:#28355c;
class renderer shared;
class screen,html,pdf output;
```What to copy: The trick is to define one node ID for the shared renderer and connect every relevant route to it. Unlike reusing an ID accidentally, this is deliberate shared identity. The resulting fan-in and fan-out shows the dependency, including why a failure in the shared component affects several outputs.
Three input sources converge on one parser and renderer, then fan out to three outputs. Reusing the same node ID makes that shared dependency explicit.
Have a Markdown file from an AI tool or a colleague? Open it in Markdific, try one of these diagrams and make it your own. If anything feels awkward, I’d love your feedback.
11. Make a planning map distinguish scope, gates and open questions
A useful mind map can show more than equally weighted branches. This release plan distinguishes committed work, a quality gate, unresolved questions and deliverables through its hierarchy and shapes.
```mermaid
%%{init: {"theme":"base","themeVariables":{"git0":"#0e7490","gitBranchLabel0":"#ffffff","cScale1":"#dbeafe","cScaleLabel1":"#172554","cScale2":"#fef3c7","cScaleLabel2":"#422006","cScale3":"#e0e7ff","cScaleLabel3":"#312e81","cScale4":"#dcfce7","cScaleLabel4":"#14532d"}}}%%
mindmap
root((Release plan))
scope[Committed scope]
Editing
Toolbar
Shortcuts
Export
Images
Page layout
gate{{Quality gate}}
Tests pass
Links checked
Assets included
questions)Open questions(
Final approver
Release date
Migration notes
outputs[Deliverables]
App package
User guide
Release notes
```What to copy: The trick is a small visual vocabulary: rectangles for work, a hexagon for the gate and a cloud for uncertainty. Those meanings are defined for this example. Indentation controls the hierarchy; the radial arrangement is not a schedule or a set of precise coordinates.
Indentation establishes parentage. Different node shapes make the quality gate and unresolved questions stand out without pretending they are ordinary feature tasks.
For syntax details, see the mind map reference.
12. Give a timeline dependencies, milestones and a critical route
A row of dates is not a useful project plan. A Gantt diagram becomes more informative when it shows which work can overlap and what must finish before approval or release.
```mermaid
gantt
title Documentation release plan
dateFormat YYYY-MM-DD
axisFormat %d %b
todayMarker off
section Prepare
Research :done, research, 2026-11-02, 2d
Outline :done, outline, after research, 1d
section Create
Draft copy :active, draft, after outline, 3d
Build diagrams :diagrams, after outline, 2d
Capture screens :screens, after diagrams, 2d
section Review
Copy review :crit, copyreview, after draft, 2d
Technical review :technical, after screens, 2d
Approval :crit, approval, after copyreview technical, 1d
section Publish
Release :milestone, release, after approval, 0d
Inspect live page :crit, inspect, after release, 1d
Review feedback :feedback, after inspect, 1d
```What to copy: The trick is to combine sections, after dependencies, milestones and selected crit tasks. Marking a bar critical is an author annotation, not proof that Mermaid calculated the critical path. The dates and durations here are illustrative; changing a label does not validate the underlying plan.
Approval waits for both copy review and technical review. A milestone marks release; it is not another multi-day work item.
For syntax details, see the Gantt reference.
Make the complexity earn its place
A richer diagram is useful when it answers something a basic diagram cannot: who owns the next step, where rejected records go, what is shared, what can overlap, or how the system recovers.
Borrow the smallest combination that answers your question. Group by responsibility, keep arrow meanings consistent and make the failure route as deliberate as the happy path. More nodes alone do not make a better diagram.
Try one example in Markdific, replace the sample labels with your own process, and inspect the result before sharing. If you try it, I’d love to hear which diagrams work well and what could be improved.
For further experiments, the official Mermaid examples and theming documentation are useful starting points. Check the final image at phone width, and keep the source with the document so the next change stays editable.
Sources and further reading
These Mermaid references cover the syntax used in the examples:
- Flowcharts: directions, subgraphs, connections and reusable classes.
- Sequence diagrams: participants, messages, alternatives and loops.
- State diagrams and entity relationships: composite states, keys and cardinality.
- Mind maps and Gantt charts: hierarchy, dependencies and milestones.
- Theme configuration: themes and diagram styling.
- Mermaid diagrams in Markdown: syntax and examples, for diagram types, fenced blocks and rendering basics.
The live documentation may include features newer than the Mermaid version in your app. Check your renderer before adopting syntax beyond these examples.








