termaid
Render Mermaid diagrams in your terminal or Python app.
Features
- 18 diagram types: flowcharts, sequence, class, ER, state, block, git, gantt, architecture, pie, treemap, mindmap, timeline, kanban, quadrant, XY chart, user journey, and packet
- Zero dependencies: pure Python, nothing to install beyond the package itself
- Terminal-aware: auto-fits diagrams to terminal width with progressive compaction
- Rich and Textual integration: colored output and TUI widgets with optional extras
- 6 color themes: default, terra, neon, mono, amber, phosphor
- ASCII fallback: works on any terminal, even the most basic ones
- Pipe-friendly CLI:
cat diagram.mmd | termaidjust works
Why?
Mermaid is great for documentation, but rendering it usually means spinning up a browser or calling an external service. termaid lets you render diagrams over SSH, in CI logs, inside TUI apps, or anywhere you have a Python environment. It was built because the existing tools in this space, like mermaid-ascii (Go) and beautiful-mermaid (TypeScript), don't offer a native Python library you can import and call directly.
Install
pip install termaid
Or try it without installing:
uvx termaid diagram.mmd
Quick start
CLI
termaid diagram.mmd
echo "graph LR; A-->B-->C" | termaid
termaid diagram.mmd --theme neon
termaid diagram.mmd --ascii
Python
from termaid import render
print(render("graph LR\n A --> B --> C"))
# Colored output (requires: pip install termaid[rich])
from termaid import render_rich
from rich import print as rprint
rprint(render_rich("graph LR\n A --> B", theme="terra"))
# Textual TUI widget (requires: pip install termaid[textual])
from termaid import MermaidWidget
widget = MermaidWidget("graph LR\n A --> B")
Supported diagram types
Flowcharts
All directions supported: LR, RL, TD/TB, BT.
graph TD
A[Start] --> B{Is valid?}
B -->|Yes| C(Process)
C --> D([Done])
B -->|No| E[Error]
┌─────────────┐
│ │
│ Start │
│ │
└──────┬──────┘
│
│
▼
┌──────◇──────┐
│ │
│ Is valid? │
│ │
└──────◇──────┘
│
│
╰──────────────────╮
Yes│ │No
▼ ▼
╭─────────────╮ ┌─────────────┐
│ │ │ │
│ Process │ │ Error │
│ │ │ │
╰──────┬──────╯ └─────────────┘
│
│
▼
╭─────────────╮
( )
( Done )
( )
╰─────────────╯
Node shapes: rectangle [text], rounded (text), diamond {text}, stadium ([text]), subroutine [[text]], circle ((text)), double circle (((text))), hexagon {{text}}, cylinder [(text)], asymmetric >text], parallelogram [/text/], trapezoid [/text\], and @{shape} syntax
Edge styles: solid -->, dotted -.->, thick ==>, bidirectional <-->, circle endpoint --o, cross endpoint --x, labeled -->|text|, variable length --->, ---->
Styling: classDef, style, linkStyle directives, :::className suffix
Subgraphs: nesting, cross-boundary edges, per-subgraph direction override
Other: %% comments, ; line separators, Markdown labels "`**bold** *italic*`", & operator (A & B --> C)
Sequence diagrams
sequenceDiagram
Alice->>Bob: Hello Bob
Bob-->>Alice: Hi Alice
Alice->>Bob: How are you?
Bob-->>Alice: Great!
┌──────────┐ ┌──────────┐
│ Alice │ │ Bob │
└──────────┘ └──────────┘
┆ Hello Bob ┆
──────────────────►
┆ Hi Alice ┆
◄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
┆ How are you? ┆
──────────────────►
┆ Great! ┆
◄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
┆ ┆
Message types: solid arrow ->>, dashed arrow -->>, solid line ->, dashed line -->
Participants: participant, actor, aliases
Class diagrams
classDiagram
class Animal {
+String name
+int age
+makeSound()
}
class Dog {
+String breed
+fetch()
}
Animal <|-- Dog
┌──────────────┐
│ Animal │
├──────────────┤
│ +String name │
│ +int age │
├──────────────┤
│ +makeSound() │
└──────────────┘
△
│
│
│
┌───────────────┐
│ Dog │
├───────────────┤
│ +String breed │
├───────────────┤
│ +fetch() │
└───────────────┘
Relationships: inheritance <|--, composition *--, aggregation o--, association --, dependency ..>, realization ..|>
Members: attributes and methods with visibility (+ public, - private, # protected, ~ package)
ER diagrams
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
┌──────────────┐
│ CUSTOMER │
└──────────────┘
│1
│ places
│
│0..*
┌──────────────┐
│ ORDER │
└──────────────┘
│1
│ contains
│
│1..*
┌──────────────┐
│ LINE-ITEM │
└──────────────┘
Cardinality: || (exactly one), o| (zero or one), }| (one or more), o{ (zero or more)
Line styles: solid --, dashed ..
Attributes: type, name, keys (PK, FK, UK), comments
State diagrams
stateDiagram-v2
[*] --> Idle
Idle --> Processing : start
Processing --> Done : complete
Done --> [*]
╭───────◯──────╮
│ │
│ ● │
│ │
╰───────◯──────╯
│
│
▼
╭──────────────╮
│ │
│ Idle │
│ │
╰───────┬──────╯
│
start│
▼
╭──────────────╮
│ │
│ Processing │
│ │
╰───────┬──────╯
│
complete│
▼
╭──────────────╮
│ │
│ Done │
│ │
╰───────┬──────╯
│
│
▼
╭───────◯──────╮
│ │
│ ◉ │
│ │
╰───────◯──────╯
Features: [*] start/end states, transition labels, state "name" as alias, composite states (state Parent { }), stereotypes (<<choice>>, <<fork>>, <<join>>)
Block diagrams
block-beta
columns 3
A["Frontend"] B["API"] C["Database"]
┌──────────┐ ┌──────────┐ ┌──────────┐
│ │ │ │ │ │
│ Frontend │ │ API │ │ Database │
│ │ │ │ │ │
└──────────┘ └──────────┘ └──────────┘
Features: columns N, column spanning (blockname:N), links between blocks, nested blocks
Git graphs
gitGraph
commit id: "init"
commit id: "feat"
branch develop
commit id: "dev-1"
commit id: "dev-2"
checkout main
commit id: "fix"
merge develop id: "merge"
main ───●─────●──────┼──────────────●──────●─
init feat │ fix merge
│ │
develop ●───────●─────────────┼
dev-1 dev-2
Directions: LR (default), TB, BT
Commands: commit (with id:, type:, tag:), branch (with order:), checkout/switch, merge, cherry-pick
Commit types: NORMAL (●), REVERSE (✖), HIGHLIGHT (■)
Config: %%{init: {"gitGraph": {"mainBranchName": "master"}}}%%
Pie charts
Yes, the syntax says pie. No, we don't draw a circle. I know. Have you ever tried to read a pie chart made of █ and ▓? Exactly. We render them as horizontal bar charts instead.
pie title Pets adopted by volunteers
"Dogs" : 386
"Cats" : 85
"Rats" : 15
Dogs┃████████████████████████████████ 79.4%
Cats┃▓▓▓▓▓▓▓ 17.5%
Rats┃░ 3.1%
Features: title, showData (display raw values), %% comments
Treemaps
treemap-beta
"Frontend"
"React": 40
"CSS": 15
"Backend"
"API": 35
"Auth": 10
┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
┆ Frontend ┆ ┆ Backend ┆
┆┌───────────────────────┐ ┌───────┐┆ ┆┌───────────────────┐ ┌────┐┆
┆│ React │ │ CSS │┆ ┆│ API │ │Auth│┆
┆│ 40 │ │ 15 │┆ ┆│ 35 │ │ 10 │┆
┆│ │ │ │┆ ┆│ │ │ │┆
┆└───────────────────────┘ └───────┘┆ ┆└───────────────────┘ └────┘┆
└┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
Features: nested sections via indentation, "label": value syntax, proportional sizing, %% comments
Mindmaps
mindmap
Project
Design
Wireframes
Mockups
Development
Frontend
Backend
Testing
╭─ Design ──╭─ Wireframes
│ ╰─ Mockups
Project ──├─ Development ──╭─ Frontend
│ ╰─ Backend
╰─ Testing
Features: indentation-based nesting, automatic overflow to the left when many children, rounded/sharp/ASCII branch characters, Mermaid shape markers stripped ((round), [square], {{hexagon}}, )cloud()
XY Charts
xychart-beta
title "Monthly Revenue"
x-axis [Jan, Feb, Mar, Apr, May, Jun]
bar [12, 18, 25, 20, 30, 35]
Monthly Revenue
35 │ ████
│ ████
│ ▄▄▄▄ ████
28 │ ████ ████
│ ▄▄▄▄ ████ ████
│ ████ ████ ████
21 │ ████ ▄▄▄▄ ████ ████
│ ▄▄▄▄ ████ ████ ████ ████
│ ████ ████ ████ ████ ████
14 │ ████ ████ ████ ████ ████
│████ ████ ████ ████ ████ ████
│████ ████ ████ ████ ████ ████
7 │████ ████ ████ ████ ████ ████
│████ ████ ████ ████ ████ ████
│████ ████ ████ ████ ████ ████
0 └──┬─────┬─────┬─────┬─────┬─────┬─
Jan Feb Mar Apr May Jun
Features: bar charts, line charts, bar+line combos, horizontal orientation (xychart horizontal), axis labels, xychart and xychart-beta keywords, rounded/sharp line corners, JSON ingest
User Journeys
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 5: Me
My working day
● Cat
◆ Me
╭───────────── Go to work ──────────────╮ ╭───────── Go home ───────────╮
╭◆─────────╮ ╭◆────────────╮ ╭●◆───────╮ ╭◆──────────────╮ ╭◆─────────╮
─│ Make tea │─│ Go upstairs │─│ Do work │────│ Go downstairs │─│ Sit down │────►
╰──────────╯ ╰─────────────╯ ╰─────────╯ ╰───────────────╯ ╰──────────╯
😄 😐 😞 😄 😄
Features: sections, satisfaction scores (😞-😄), multi-actor support with distinct symbols (●◆■▲), rounded/sharp/ASCII corners
Packet Diagrams
packet
0-15: "Source Port"
16-31: "Destination Port"
32-63: "Sequence Number"
64-95: "Acknowledgment Number"
0 15 16 31
╭───────────────────────────────────────────────┬───────────────────────────────────────────────╮
│ Source Port │ Destination Port │
╰───────────────────────────────────────────────┴───────────────────────────────────────────────╯
32 63
╭───────────────────────────────────────────────────────────────────────────────────────────────╮
│ Sequence Number │
╰───────────────────────────────────────────────────────────────────────────────────────────────╯
64 95
╭───────────────────────────────────────────────────────────────────────────────────────────────╮
│ Acknowledgment Number │
╰───────────────────────────────────────────────────────────────────────────────────────────────╯
Features: bit-aligned field layouts, boundary numbers, auto-increment (+N) syntax, separated boxes per row, truncated label legend with bit ranges, packet and packet-beta keywords
CLI options
| Flag | Description |
|---|---|
--ascii |
ASCII-only output (no Unicode box-drawing) |
--theme NAME |
Color theme (requires pip install termaid[rich]). Use --themes to list |
--themes |
List all available color themes |
--demo [TYPE] |
Render sample diagrams (all, flowchart, sequence, mindmap, etc.) |
--padding-x N |
Horizontal padding inside boxes (default: 4) |
--padding-y N |
Vertical padding inside boxes (default: 2) |
--gap N |
Space between nodes (default: 4). Use 1 or 2 for compact diagrams |
--inline-edge-labels |
Attach flowchart labels directly to their edges |
--width N |
Max output width. Re-renders with smaller gap/padding if exceeded |
--no-auto-fit |
Disable automatic compaction when diagram exceeds terminal width |
--sharp-edges |
Sharp corners on edge turns instead of rounded |
-o FILE |
Write output to file instead of stdout |
--show-ids |
Show node IDs alongside labels for debugging (e.g. myId: My Label) |
--json TYPE |
Pipe JSON/tabular data and render as treemap, pie, mindmap, flowchart, or xychart |
--tui |
Interactive TUI viewer (requires pip install termaid[tui]) |
Python API
render(source, ...) -> str
Render a Mermaid diagram as a plain text string. Auto-detects diagram type.
render_rich(source, ..., theme="default") -> rich.text.Text
Render as a Rich Text object with colors. Requires pip install termaid[rich].
MermaidWidget
A Textual widget with a reactive source attribute. Requires pip install termaid[textual]. Updates live when you change the source property.
from termaid import MermaidWidget
class MyApp(App):
def compose(self):
yield MermaidWidget("graph LR\n A --> B")
Themes
11 built-in themes for --theme / render_rich(). Run termaid --themes to list them.
Text themes (foreground colors only):
| Theme | Colors | Description |
|---|---|---|
default |
Cyan nodes, yellow arrows, white labels | |
terra |
Warm earth tones (browns, oranges) | |
neon |
Magenta nodes, green arrows, cyan edges | |
mono |
White/gray monochrome | |
amber |
Amber/gold CRT-style | |
phosphor |
Green phosphor terminal-style |
Solid themes (filled backgrounds with foreground colors):
| Theme | Colors | Description |
|---|---|---|
gruvbox |
Gruvbox dark palette | |
monokai |
Monokai dark with pink/green accents | |
dracula |
Dracula purple/pink/green palette | |
nord |
Nord muted blue/cyan arctic palette | |
solarized |
Solarized dark blue/yellow/cyan |
Optional extras
pip install termaid[rich] # Colored terminal output
pip install termaid[textual] # Textual TUI widget
Limitations
- Layout engine is approximate. Node positioning uses a grid-based barycenter heuristic. Very dense graphs may still produce some edge crossings.
- Manhattan-only edge routing. Edges use A* pathfinding on a grid. The engine auto-expands gaps for crossing edges and biases toward flow-aligned routes.
- Wide diagrams. The CLI auto-compacts when the diagram exceeds terminal width. For very wide LR chains, use
--width N,--gap 1, or pipe throughless -S.
Gallery
See the examples page for rendered examples of all 18 supported diagram types.
Acknowledgements
Inspired by mermaid-ascii by Alexander Grooff and beautiful-mermaid by Lukilabs.
License
MIT
Metadata
Release files for termaid 0.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| termaid-0.9.0.tar.gz | 438.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| termaid-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 605.0 kB
Release files / termaid-0.9.0.tar.gz
| Download URL | termaid-0.9.0.tar.gz |
|---|---|
| Size | 438.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0b183f139638015b0a8d52be214050187ea1e944c2c6f86b404c675c9e3c7ad6
|
|
BLAKE2b-256 checksum How to use checksums |
3a6f56eab35efefdbee574ab59aa1b715781a89ae63888dbdd910c29e3435792
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.
Transparency logRelease files / termaid-0.9.0-py3-none-any.whl
| Download URL | termaid-0.9.0-py3-none-any.whl |
|---|---|
| Size | 166.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
793287486983d1be8cc6bb826340206af0a07676b8c25c0683ef3afe9870ac9d
|
|
BLAKE2b-256 checksum How to use checksums |
427becd6564a681a84cd9000f028752c1b9226c15df2d992af2af19ab3439dee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.
Transparency log