@ktrysmt/beautiful-mermaid 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +585 -0
  3. package/dist/index.d.ts +312 -0
  4. package/dist/index.js +9312 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +61 -0
  7. package/src/__tests__/ascii-edge-styles.test.ts +134 -0
  8. package/src/__tests__/ascii-multiline.test.ts +175 -0
  9. package/src/__tests__/ascii.test.ts +251 -0
  10. package/src/__tests__/class-arrow-directions.test.ts +414 -0
  11. package/src/__tests__/class-integration.test.ts +115 -0
  12. package/src/__tests__/class-parser.test.ts +238 -0
  13. package/src/__tests__/edge-approach-direction.test.ts +296 -0
  14. package/src/__tests__/er-integration.test.ts +432 -0
  15. package/src/__tests__/er-parser.test.ts +187 -0
  16. package/src/__tests__/integration.test.ts +518 -0
  17. package/src/__tests__/layout-disconnected.test.ts +391 -0
  18. package/src/__tests__/linkstyle.test.ts +98 -0
  19. package/src/__tests__/multiline-labels.test.ts +845 -0
  20. package/src/__tests__/parser.test.ts +861 -0
  21. package/src/__tests__/pathfinder.test.ts +132 -0
  22. package/src/__tests__/renderer.test.ts +544 -0
  23. package/src/__tests__/sequence-integration.test.ts +118 -0
  24. package/src/__tests__/sequence-layout.test.ts +747 -0
  25. package/src/__tests__/sequence-parser.test.ts +233 -0
  26. package/src/__tests__/styles.test.ts +182 -0
  27. package/src/__tests__/testdata/ascii/ampersand_lhs.txt +18 -0
  28. package/src/__tests__/testdata/ascii/ampersand_lhs_and_rhs.txt +18 -0
  29. package/src/__tests__/testdata/ascii/ampersand_rhs.txt +18 -0
  30. package/src/__tests__/testdata/ascii/ampersand_td_fanin.txt +18 -0
  31. package/src/__tests__/testdata/ascii/ampersand_td_fanout.txt +18 -0
  32. package/src/__tests__/testdata/ascii/ampersand_without_edge.txt +18 -0
  33. package/src/__tests__/testdata/ascii/back_reference_from_child.txt +10 -0
  34. package/src/__tests__/testdata/ascii/backlink_from_bottom.txt +22 -0
  35. package/src/__tests__/testdata/ascii/backlink_from_top.txt +22 -0
  36. package/src/__tests__/testdata/ascii/backlink_with_short_y_padding.txt +20 -0
  37. package/src/__tests__/testdata/ascii/cls_all_relationships.txt +17 -0
  38. package/src/__tests__/testdata/ascii/cls_annotation.txt +31 -0
  39. package/src/__tests__/testdata/ascii/cls_association.txt +14 -0
  40. package/src/__tests__/testdata/ascii/cls_basic.txt +15 -0
  41. package/src/__tests__/testdata/ascii/cls_dependency.txt +14 -0
  42. package/src/__tests__/testdata/ascii/cls_inheritance.txt +22 -0
  43. package/src/__tests__/testdata/ascii/cls_methods.txt +21 -0
  44. package/src/__tests__/testdata/ascii/comments.txt +23 -0
  45. package/src/__tests__/testdata/ascii/custom_padding.txt +10 -0
  46. package/src/__tests__/testdata/ascii/duplicate_labels.txt +19 -0
  47. package/src/__tests__/testdata/ascii/er_attributes.txt +19 -0
  48. package/src/__tests__/testdata/ascii/er_basic.txt +8 -0
  49. package/src/__tests__/testdata/ascii/er_identifying.txt +16 -0
  50. package/src/__tests__/testdata/ascii/flowchart_tb_simple.txt +29 -0
  51. package/src/__tests__/testdata/ascii/graph_bt_direction.txt +28 -0
  52. package/src/__tests__/testdata/ascii/graph_tb_direction.txt +26 -0
  53. package/src/__tests__/testdata/ascii/nested_subgraphs_with_labels.txt +36 -0
  54. package/src/__tests__/testdata/ascii/preserve_order_of_definition.txt +23 -0
  55. package/src/__tests__/testdata/ascii/self_reference.txt +10 -0
  56. package/src/__tests__/testdata/ascii/self_reference_with_edge.txt +10 -0
  57. package/src/__tests__/testdata/ascii/seq_basic.txt +17 -0
  58. package/src/__tests__/testdata/ascii/seq_multiple_messages.txt +25 -0
  59. package/src/__tests__/testdata/ascii/seq_self_message.txt +18 -0
  60. package/src/__tests__/testdata/ascii/single_node.txt +8 -0
  61. package/src/__tests__/testdata/ascii/single_node_longer_name.txt +8 -0
  62. package/src/__tests__/testdata/ascii/subgraph_complex_mixed.txt +38 -0
  63. package/src/__tests__/testdata/ascii/subgraph_complex_nested.txt +49 -0
  64. package/src/__tests__/testdata/ascii/subgraph_direction_override.txt +37 -0
  65. package/src/__tests__/testdata/ascii/subgraph_empty.txt +10 -0
  66. package/src/__tests__/testdata/ascii/subgraph_mixed_nodes.txt +20 -0
  67. package/src/__tests__/testdata/ascii/subgraph_mixed_nodes_td.txt +48 -0
  68. package/src/__tests__/testdata/ascii/subgraph_multiple_edges.txt +32 -0
  69. package/src/__tests__/testdata/ascii/subgraph_multiple_nodes.txt +16 -0
  70. package/src/__tests__/testdata/ascii/subgraph_nested.txt +24 -0
  71. package/src/__tests__/testdata/ascii/subgraph_nested_with_external.txt +30 -0
  72. package/src/__tests__/testdata/ascii/subgraph_node_outside_lr.txt +17 -0
  73. package/src/__tests__/testdata/ascii/subgraph_single_node.txt +16 -0
  74. package/src/__tests__/testdata/ascii/subgraph_td_direction.txt +26 -0
  75. package/src/__tests__/testdata/ascii/subgraph_td_multiple.txt +44 -0
  76. package/src/__tests__/testdata/ascii/subgraph_td_multiple_paddingy.txt +42 -0
  77. package/src/__tests__/testdata/ascii/subgraph_three_levels_nested.txt +32 -0
  78. package/src/__tests__/testdata/ascii/subgraph_three_separate.txt +24 -0
  79. package/src/__tests__/testdata/ascii/subgraph_two_separate.txt +20 -0
  80. package/src/__tests__/testdata/ascii/subgraph_with_labels.txt +20 -0
  81. package/src/__tests__/testdata/ascii/three_nodes.txt +9 -0
  82. package/src/__tests__/testdata/ascii/three_nodes_single_line.txt +8 -0
  83. package/src/__tests__/testdata/ascii/two_layer_single_graph.txt +19 -0
  84. package/src/__tests__/testdata/ascii/two_layer_single_graph_longer_names.txt +19 -0
  85. package/src/__tests__/testdata/ascii/two_nodes_linked.txt +8 -0
  86. package/src/__tests__/testdata/ascii/two_nodes_longer_names.txt +8 -0
  87. package/src/__tests__/testdata/ascii/two_root_nodes.txt +19 -0
  88. package/src/__tests__/testdata/ascii/two_root_nodes_longer_names.txt +19 -0
  89. package/src/__tests__/testdata/ascii/two_single_root_nodes.txt +19 -0
  90. package/src/__tests__/testdata/unicode/ampersand_lhs.txt +18 -0
  91. package/src/__tests__/testdata/unicode/ampersand_lhs_and_rhs.txt +18 -0
  92. package/src/__tests__/testdata/unicode/ampersand_rhs.txt +18 -0
  93. package/src/__tests__/testdata/unicode/ampersand_without_edge.txt +18 -0
  94. package/src/__tests__/testdata/unicode/back_reference_from_child.txt +10 -0
  95. package/src/__tests__/testdata/unicode/backlink_from_bottom.txt +22 -0
  96. package/src/__tests__/testdata/unicode/backlink_from_top.txt +22 -0
  97. package/src/__tests__/testdata/unicode/cls_all_relationships.txt +17 -0
  98. package/src/__tests__/testdata/unicode/cls_annotation.txt +31 -0
  99. package/src/__tests__/testdata/unicode/cls_association.txt +14 -0
  100. package/src/__tests__/testdata/unicode/cls_basic.txt +15 -0
  101. package/src/__tests__/testdata/unicode/cls_dependency.txt +14 -0
  102. package/src/__tests__/testdata/unicode/cls_inheritance.txt +22 -0
  103. package/src/__tests__/testdata/unicode/cls_methods.txt +21 -0
  104. package/src/__tests__/testdata/unicode/comments.txt +23 -0
  105. package/src/__tests__/testdata/unicode/duplicate_labels.txt +19 -0
  106. package/src/__tests__/testdata/unicode/er_attributes.txt +19 -0
  107. package/src/__tests__/testdata/unicode/er_basic.txt +8 -0
  108. package/src/__tests__/testdata/unicode/er_identifying.txt +16 -0
  109. package/src/__tests__/testdata/unicode/graph_bt_direction.txt +28 -0
  110. package/src/__tests__/testdata/unicode/preserve_order_of_definition.txt +23 -0
  111. package/src/__tests__/testdata/unicode/self_reference.txt +10 -0
  112. package/src/__tests__/testdata/unicode/self_reference_with_edge.txt +10 -0
  113. package/src/__tests__/testdata/unicode/seq_basic.txt +17 -0
  114. package/src/__tests__/testdata/unicode/seq_multiple_messages.txt +25 -0
  115. package/src/__tests__/testdata/unicode/seq_self_message.txt +18 -0
  116. package/src/__tests__/testdata/unicode/single_node.txt +8 -0
  117. package/src/__tests__/testdata/unicode/single_node_longer_name.txt +8 -0
  118. package/src/__tests__/testdata/unicode/three_nodes.txt +9 -0
  119. package/src/__tests__/testdata/unicode/three_nodes_single_line.txt +8 -0
  120. package/src/__tests__/testdata/unicode/two_layer_single_graph.txt +19 -0
  121. package/src/__tests__/testdata/unicode/two_layer_single_graph_longer_names.txt +19 -0
  122. package/src/__tests__/testdata/unicode/two_nodes_linked.txt +8 -0
  123. package/src/__tests__/testdata/unicode/two_nodes_longer_names.txt +8 -0
  124. package/src/__tests__/testdata/unicode/two_root_nodes.txt +19 -0
  125. package/src/__tests__/testdata/unicode/two_root_nodes_longer_names.txt +19 -0
  126. package/src/__tests__/testdata/unicode/two_single_root_nodes.txt +19 -0
  127. package/src/__tests__/text-metrics.test.ts +256 -0
  128. package/src/__tests__/xychart-ascii.test.ts +310 -0
  129. package/src/__tests__/xychart-integration.test.ts +137 -0
  130. package/src/ascii/ansi.ts +447 -0
  131. package/src/ascii/canvas.ts +431 -0
  132. package/src/ascii/class-diagram.ts +697 -0
  133. package/src/ascii/converter.ts +271 -0
  134. package/src/ascii/draw.ts +1373 -0
  135. package/src/ascii/edge-bundling.ts +328 -0
  136. package/src/ascii/edge-routing.ts +296 -0
  137. package/src/ascii/er-diagram.ts +435 -0
  138. package/src/ascii/grid.ts +596 -0
  139. package/src/ascii/index.ts +171 -0
  140. package/src/ascii/multiline-utils.ts +77 -0
  141. package/src/ascii/pathfinder.ts +227 -0
  142. package/src/ascii/sequence.ts +451 -0
  143. package/src/ascii/shapes/circle.ts +27 -0
  144. package/src/ascii/shapes/corners.ts +127 -0
  145. package/src/ascii/shapes/diamond.ts +27 -0
  146. package/src/ascii/shapes/hexagon.ts +27 -0
  147. package/src/ascii/shapes/index.ts +101 -0
  148. package/src/ascii/shapes/rectangle.ts +173 -0
  149. package/src/ascii/shapes/rounded.ts +27 -0
  150. package/src/ascii/shapes/special.ts +293 -0
  151. package/src/ascii/shapes/stadium.ts +112 -0
  152. package/src/ascii/shapes/state.ts +192 -0
  153. package/src/ascii/shapes/types.ts +73 -0
  154. package/src/ascii/types.ts +273 -0
  155. package/src/ascii/validate.ts +120 -0
  156. package/src/ascii/xychart.ts +863 -0
  157. package/src/browser.ts +24 -0
  158. package/src/class/layout.ts +211 -0
  159. package/src/class/parser.ts +290 -0
  160. package/src/class/renderer.ts +397 -0
  161. package/src/class/types.ts +121 -0
  162. package/src/elk-instance.ts +113 -0
  163. package/src/er/layout.ts +161 -0
  164. package/src/er/parser.ts +181 -0
  165. package/src/er/renderer.ts +420 -0
  166. package/src/er/types.ts +91 -0
  167. package/src/index.ts +177 -0
  168. package/src/layout-engine.ts +1421 -0
  169. package/src/layout.ts +8 -0
  170. package/src/multiline-utils.ts +219 -0
  171. package/src/parser.ts +645 -0
  172. package/src/renderer.ts +603 -0
  173. package/src/sequence/layout.ts +410 -0
  174. package/src/sequence/parser.ts +207 -0
  175. package/src/sequence/renderer.ts +346 -0
  176. package/src/sequence/types.ts +146 -0
  177. package/src/shape-clipping.ts +179 -0
  178. package/src/styles.ts +96 -0
  179. package/src/text-metrics.ts +246 -0
  180. package/src/theme.ts +304 -0
  181. package/src/types.ts +164 -0
  182. package/src/xychart/colors.ts +140 -0
  183. package/src/xychart/layout.ts +440 -0
  184. package/src/xychart/parser.ts +115 -0
  185. package/src/xychart/renderer.ts +549 -0
  186. package/src/xychart/types.ts +150 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Craft Docs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,585 @@
1
+ <div align="center">
2
+
3
+ # beautiful-mermaid
4
+
5
+ **Render Mermaid diagrams as beautiful SVGs or ASCII art**
6
+
7
+ Ultra-fast, fully themeable, zero DOM dependencies. Built for the AI era.
8
+
9
+ ![beautiful-mermaid sequence diagram example](hero.png)
10
+
11
+ [![npm version](https://img.shields.io/npm/v/beautiful-mermaid.svg)](https://www.npmjs.com/package/beautiful-mermaid)
12
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
13
+
14
+ [**Live Demo & Samples**](https://agents.craft.do/mermaid)
15
+
16
+ **[→ Use it live in Craft Agents](https://agents.craft.do)**
17
+
18
+ </div>
19
+
20
+ ---
21
+
22
+ ## Why We Built This
23
+
24
+ Diagrams are essential for AI-assisted programming. When you're working with an AI coding assistant, being able to visualize data flows, state machines, and system architecture—directly in your terminal or chat interface—makes complex concepts instantly graspable.
25
+
26
+ [Mermaid](https://mermaid.js.org/) is the de facto standard for text-based diagrams. It's brilliant. But the default renderer has problems:
27
+
28
+ - **Aesthetics** — Might be personal preference, but wished they looked more professional
29
+ - **Complex theming** — Customizing colors requires wrestling with CSS classes
30
+ - **No terminal output** — Can't render to ASCII for CLI tools
31
+ - **Heavy dependencies** — Pulls in a lot of code for simple diagrams
32
+
33
+ We built `beautiful-mermaid` at [Craft](https://craft.do) to power diagrams in [Craft Agents](https://agents.craft.do). It's fast, beautiful, and works everywhere—from rich UIs to plain terminals.
34
+
35
+
36
+ The ASCII rendering engine is based on [mermaid-ascii](https://github.com/AlexanderGrooff/mermaid-ascii) by Alexander Grooff. We ported it from Go to TypeScript and extended it. Thank you Alexander for the excellent foundation! (And inspiration that this was possible.)
37
+
38
+ ## Features
39
+
40
+ - **6 diagram types** — Flowcharts, State, Sequence, Class, ER, and XY Charts (bar, line, combined)
41
+ - **Dual output** — SVG for rich UIs, ASCII/Unicode for terminals
42
+ - **Synchronous rendering** — No async, no flash. Works with React `useMemo()`
43
+ - **15 built-in themes** — And dead simple to add your own
44
+ - **Full Shiki compatibility** — Use any VS Code theme directly
45
+ - **Live theme switching** — CSS custom properties, no re-render needed
46
+ - **Mono mode** — Beautiful diagrams from just 2 colors
47
+ - **Zero DOM dependencies** — Pure TypeScript, works everywhere
48
+ - **Ultra-fast** — Renders 100+ diagrams in under 500ms
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ npm install beautiful-mermaid
54
+ # or
55
+ bun add beautiful-mermaid
56
+ # or
57
+ pnpm add beautiful-mermaid
58
+ ```
59
+
60
+ ## Quick Start
61
+
62
+ ### SVG Output
63
+
64
+ ```typescript
65
+ import { renderMermaidSVG } from 'beautiful-mermaid'
66
+
67
+ const svg = renderMermaidSVG(`
68
+ graph TD
69
+ A[Start] --> B{Decision}
70
+ B -->|Yes| C[Action]
71
+ B -->|No| D[End]
72
+ `)
73
+ ```
74
+
75
+ Rendering is **fully synchronous** — no `await`, no promises. The ELK.js layout engine runs synchronously via a FakeWorker bypass, so you get your SVG string instantly.
76
+
77
+ Need async? Use `renderMermaidSVGAsync()` — same output, returns a `Promise<string>`.
78
+
79
+ ### ASCII Output
80
+
81
+ ```typescript
82
+ import { renderMermaidASCII } from 'beautiful-mermaid'
83
+
84
+ const ascii = renderMermaidASCII(`graph LR; A --> B --> C`)
85
+ ```
86
+
87
+ ```
88
+ ┌───┐ ┌───┐ ┌───┐
89
+ │ │ │ │ │ │
90
+ │ A │────►│ B │────►│ C │
91
+ │ │ │ │ │ │
92
+ └───┘ └───┘ └───┘
93
+ ```
94
+
95
+ ---
96
+
97
+ ## React Integration
98
+
99
+ Because rendering is synchronous, you can use `useMemo()` for zero-flash diagram rendering:
100
+
101
+ ```tsx
102
+ import { renderMermaidSVG } from 'beautiful-mermaid'
103
+
104
+ function MermaidDiagram({ code }: { code: string }) {
105
+ const { svg, error } = React.useMemo(() => {
106
+ try {
107
+ return {
108
+ svg: renderMermaidSVG(code, {
109
+ bg: 'var(--background)',
110
+ fg: 'var(--foreground)',
111
+ transparent: true,
112
+ }),
113
+ error: null,
114
+ }
115
+ } catch (err) {
116
+ return { svg: null, error: err instanceof Error ? err : new Error(String(err)) }
117
+ }
118
+ }, [code])
119
+
120
+ if (error) return <pre>{error.message}</pre>
121
+ return <div dangerouslySetInnerHTML={{ __html: svg! }} />
122
+ }
123
+ ```
124
+
125
+ **Why this works well:**
126
+ - **No flash** — SVG is computed synchronously during render, not in a useEffect
127
+ - **CSS variables** — Pass `var(--background)` etc. instead of hex colors. The SVG inherits from your app's CSS, so theme switches apply instantly without re-rendering
128
+ - **Memoized** — Only re-renders when `code` changes
129
+
130
+ ---
131
+
132
+ ## Theming
133
+
134
+ The theming system is the heart of `beautiful-mermaid`. It's designed to be both powerful and dead simple.
135
+
136
+ ### The Two-Color Foundation
137
+
138
+ Every diagram needs just two colors: **background** (`bg`) and **foreground** (`fg`). That's it. From these two colors, the entire diagram is derived using `color-mix()`:
139
+
140
+ ```typescript
141
+ const svg = renderMermaidSVG(diagram, {
142
+ bg: '#1a1b26', // Background
143
+ fg: '#a9b1d6', // Foreground
144
+ })
145
+ ```
146
+
147
+ This is **Mono Mode**—a coherent, beautiful diagram from just two colors. The system automatically derives:
148
+
149
+ | Element | Derivation |
150
+ |---------|------------|
151
+ | Text | `--fg` at 100% |
152
+ | Secondary text | `--fg` at 60% into `--bg` |
153
+ | Edge labels | `--fg` at 40% into `--bg` |
154
+ | Faint text | `--fg` at 25% into `--bg` |
155
+ | Connectors | `--fg` at 50% into `--bg` |
156
+ | Arrow heads | `--fg` at 85% into `--bg` |
157
+ | Node fill | `--fg` at 3% into `--bg` |
158
+ | Group header | `--fg` at 5% into `--bg` |
159
+ | Inner strokes | `--fg` at 12% into `--bg` |
160
+ | Node stroke | `--fg` at 20% into `--bg` |
161
+
162
+ ### Enriched Mode
163
+
164
+ For richer themes, you can provide optional "enrichment" colors that override specific derivations:
165
+
166
+ ```typescript
167
+ const svg = renderMermaidSVG(diagram, {
168
+ bg: '#1a1b26',
169
+ fg: '#a9b1d6',
170
+ // Optional enrichment:
171
+ line: '#3d59a1', // Edge/connector color
172
+ accent: '#7aa2f7', // Arrow heads, highlights
173
+ muted: '#565f89', // Secondary text, labels
174
+ surface: '#292e42', // Node fill tint
175
+ border: '#3d59a1', // Node stroke
176
+ })
177
+ ```
178
+
179
+ If an enrichment color isn't provided, it falls back to the `color-mix()` derivation. This means you can provide just the colors you care about.
180
+
181
+ ### CSS Custom Properties = Live Switching
182
+
183
+ All colors are CSS custom properties on the `<svg>` element. This means you can switch themes instantly without re-rendering:
184
+
185
+ ```javascript
186
+ // Switch theme by updating CSS variables
187
+ svg.style.setProperty('--bg', '#282a36')
188
+ svg.style.setProperty('--fg', '#f8f8f2')
189
+ // The entire diagram updates immediately
190
+ ```
191
+
192
+ For React apps, pass CSS variable references instead of hex values:
193
+
194
+ ```typescript
195
+ const svg = renderMermaidSVG(diagram, {
196
+ bg: 'var(--background)',
197
+ fg: 'var(--foreground)',
198
+ accent: 'var(--accent)',
199
+ transparent: true,
200
+ })
201
+ // Theme switches apply automatically via CSS cascade — no re-render needed
202
+ ```
203
+
204
+ ### Built-in Themes
205
+
206
+ 15 carefully curated themes ship out of the box:
207
+
208
+ | Theme | Type | Background | Accent |
209
+ |-------|------|------------|--------|
210
+ | `zinc-light` | Light | `#FFFFFF` | Derived |
211
+ | `zinc-dark` | Dark | `#18181B` | Derived |
212
+ | `tokyo-night` | Dark | `#1a1b26` | `#7aa2f7` |
213
+ | `tokyo-night-storm` | Dark | `#24283b` | `#7aa2f7` |
214
+ | `tokyo-night-light` | Light | `#d5d6db` | `#34548a` |
215
+ | `catppuccin-mocha` | Dark | `#1e1e2e` | `#cba6f7` |
216
+ | `catppuccin-latte` | Light | `#eff1f5` | `#8839ef` |
217
+ | `nord` | Dark | `#2e3440` | `#88c0d0` |
218
+ | `nord-light` | Light | `#eceff4` | `#5e81ac` |
219
+ | `dracula` | Dark | `#282a36` | `#bd93f9` |
220
+ | `github-light` | Light | `#ffffff` | `#0969da` |
221
+ | `github-dark` | Dark | `#0d1117` | `#4493f8` |
222
+ | `solarized-light` | Light | `#fdf6e3` | `#268bd2` |
223
+ | `solarized-dark` | Dark | `#002b36` | `#268bd2` |
224
+ | `one-dark` | Dark | `#282c34` | `#c678dd` |
225
+
226
+ ```typescript
227
+ import { renderMermaidSVG, THEMES } from 'beautiful-mermaid'
228
+
229
+ const svg = renderMermaidSVG(diagram, THEMES['tokyo-night'])
230
+ ```
231
+
232
+ ### Adding Your Own Theme
233
+
234
+ Creating a theme is trivial. At minimum, just provide `bg` and `fg`:
235
+
236
+ ```typescript
237
+ const myTheme = {
238
+ bg: '#0f0f0f',
239
+ fg: '#e0e0e0',
240
+ }
241
+
242
+ const svg = renderMermaidSVG(diagram, myTheme)
243
+ ```
244
+
245
+ Want richer colors? Add any of the optional enrichments:
246
+
247
+ ```typescript
248
+ const myRichTheme = {
249
+ bg: '#0f0f0f',
250
+ fg: '#e0e0e0',
251
+ accent: '#ff6b6b', // Pop of color for arrows
252
+ muted: '#666666', // Subdued labels
253
+ }
254
+ ```
255
+
256
+ ### Full Shiki Compatibility
257
+
258
+ Use **any VS Code theme** directly via Shiki integration. This gives you access to hundreds of community themes:
259
+
260
+ ```typescript
261
+ import { getSingletonHighlighter } from 'shiki'
262
+ import { renderMermaidSVG, fromShikiTheme } from 'beautiful-mermaid'
263
+
264
+ // Load any theme from Shiki's registry
265
+ const highlighter = await getSingletonHighlighter({
266
+ themes: ['vitesse-dark', 'rose-pine', 'material-theme-darker']
267
+ })
268
+
269
+ // Extract diagram colors from the theme
270
+ const colors = fromShikiTheme(highlighter.getTheme('vitesse-dark'))
271
+
272
+ const svg = renderMermaidSVG(diagram, colors)
273
+ ```
274
+
275
+ The `fromShikiTheme()` function intelligently maps VS Code editor colors to diagram roles:
276
+
277
+ | Editor Color | Diagram Role |
278
+ |--------------|--------------|
279
+ | `editor.background` | `bg` |
280
+ | `editor.foreground` | `fg` |
281
+ | `editorLineNumber.foreground` | `line` |
282
+ | `focusBorder` / keyword token | `accent` |
283
+ | comment token | `muted` |
284
+ | `editor.selectionBackground` | `surface` |
285
+ | `editorWidget.border` | `border` |
286
+
287
+ ---
288
+
289
+ ## Supported Diagrams
290
+
291
+ ### Flowcharts
292
+
293
+ ```
294
+ graph TD
295
+ A[Start] --> B{Decision}
296
+ B -->|Yes| C[Process]
297
+ B -->|No| D[End]
298
+ C --> D
299
+ ```
300
+
301
+ All directions supported: `TD` (top-down), `LR` (left-right), `BT` (bottom-top), `RL` (right-left).
302
+
303
+ ### State Diagrams
304
+
305
+ ```
306
+ stateDiagram-v2
307
+ [*] --> Idle
308
+ Idle --> Processing: start
309
+ Processing --> Complete: done
310
+ Complete --> [*]
311
+ ```
312
+
313
+ ### Sequence Diagrams
314
+
315
+ ```
316
+ sequenceDiagram
317
+ Alice->>Bob: Hello Bob!
318
+ Bob-->>Alice: Hi Alice!
319
+ Alice->>Bob: How are you?
320
+ Bob-->>Alice: Great, thanks!
321
+ ```
322
+
323
+ ### Class Diagrams
324
+
325
+ ```
326
+ classDiagram
327
+ Animal <|-- Duck
328
+ Animal <|-- Fish
329
+ Animal: +int age
330
+ Animal: +String gender
331
+ Animal: +isMammal() bool
332
+ Duck: +String beakColor
333
+ Duck: +swim()
334
+ Duck: +quack()
335
+ ```
336
+
337
+ ### ER Diagrams
338
+
339
+ ```
340
+ erDiagram
341
+ CUSTOMER ||--o{ ORDER : places
342
+ ORDER ||--|{ LINE_ITEM : contains
343
+ PRODUCT ||--o{ LINE_ITEM : "is in"
344
+ ```
345
+
346
+ ### Inline Edge Styling
347
+
348
+ Use `linkStyle` to override edge colors and stroke widths — just like [Mermaid's linkStyle](https://mermaid.js.org/syntax/flowchart.html#styling-links):
349
+
350
+ ```
351
+ graph TD
352
+ A --> B --> C
353
+ linkStyle 0 stroke:#ff0000,stroke-width:2px
354
+ linkStyle default stroke:#888888
355
+ ```
356
+
357
+ | Syntax | Effect |
358
+ | ------------------------------- | -------------------------------------- |
359
+ | `linkStyle 0 stroke:#f00` | Style a single edge by index (0-based) |
360
+ | `linkStyle 0,2 stroke:#f00` | Style multiple edges at once |
361
+ | `linkStyle default stroke:#888` | Default style applied to all edges |
362
+
363
+ Index-specific styles override the default. Supported properties: `stroke`, `stroke-width`.
364
+
365
+ Works in both flowcharts and state diagrams.
366
+
367
+ ### XY Charts
368
+
369
+ Bar charts, line charts, and combinations — using Mermaid's `xychart-beta` syntax.
370
+
371
+ **Bar chart:**
372
+
373
+ ```
374
+ xychart-beta
375
+ title "Monthly Revenue"
376
+ x-axis [Jan, Feb, Mar, Apr, May, Jun]
377
+ y-axis "Revenue ($K)" 0 --> 500
378
+ bar [180, 250, 310, 280, 350, 420]
379
+ ```
380
+
381
+ **Line chart:**
382
+
383
+ ```
384
+ xychart-beta
385
+ title "User Growth"
386
+ x-axis [Jan, Feb, Mar, Apr, May, Jun]
387
+ line [1200, 1800, 2500, 3100, 3800, 4500]
388
+ ```
389
+
390
+ **Combined bar + line:**
391
+
392
+ ```
393
+ xychart-beta
394
+ title "Sales with Trend"
395
+ x-axis [Jan, Feb, Mar, Apr, May, Jun]
396
+ bar [300, 380, 280, 450, 350, 520]
397
+ line [300, 330, 320, 353, 352, 395]
398
+ ```
399
+
400
+ **Horizontal orientation:**
401
+
402
+ ```
403
+ xychart-beta horizontal
404
+ title "Language Popularity"
405
+ x-axis [Python, JavaScript, Java, Go, Rust]
406
+ bar [30, 25, 20, 12, 8]
407
+ ```
408
+
409
+ **Axis configuration:**
410
+
411
+ - Categorical x-axis: `x-axis [A, B, C]`
412
+ - Numeric x-axis range: `x-axis 0 --> 100`
413
+ - Axis titles: `x-axis "Category" [A, B, C]`
414
+ - Y-axis range: `y-axis "Score" 0 --> 100`
415
+
416
+ **Multi-series:** Add multiple `bar` and/or `line` declarations. Each series gets a distinct color from a monochromatic palette derived from the theme's accent color.
417
+
418
+ ### XY Chart Styling
419
+
420
+ The chart renderer follows a clean, minimal design philosophy inspired by Apple and Craft:
421
+
422
+ - **Dot grid** — A subtle dot pattern fills the plot area instead of traditional solid grid lines
423
+ - **Rounded bars** — All bar corners are rounded for a modern, polished look
424
+ - **Smooth curves** — Line series use natural cubic spline interpolation, producing mathematically smooth curves through all data points (not straight segments or staircase steps)
425
+ - **Floating labels** — No visible axis lines or tick marks; labels float freely for a clutter-free aesthetic
426
+ - **Drop-shadow lines** — Each line series has a subtle shadow beneath it for depth
427
+ - **Monochromatic palette** — Series 0 uses the theme's accent color; additional series get darker/lighter shades of the same hue with subtle hue drift, adapting automatically to light or dark backgrounds
428
+ - **Interactive tooltips** — When rendered with `interactive: true`, hovering over bars or data points shows value tooltips. Multi-line tooltips appear when multiple series share an x-position
429
+ - **Sparse line dots** — Lines with 12 or fewer data points show data point dots by default for readability
430
+ - **Full theme support** — All 15 built-in themes (and custom themes) apply to charts. The accent color drives the entire series color palette
431
+ - **Live theme switching** — Chart series colors are CSS custom properties (`--xychart-color-N`), so theme changes apply instantly without re-rendering
432
+
433
+ ---
434
+
435
+ ## ASCII Output
436
+
437
+ For terminal environments, CLI tools, or anywhere you need plain text, render to ASCII or Unicode box-drawing characters:
438
+
439
+ ```typescript
440
+ import { renderMermaidASCII } from 'beautiful-mermaid'
441
+
442
+ // Unicode mode (default) — prettier box drawing
443
+ const unicode = renderMermaidASCII(`graph LR; A --> B`)
444
+
445
+ // Pure ASCII mode — maximum compatibility
446
+ const ascii = renderMermaidASCII(`graph LR; A --> B`, { useAscii: true })
447
+ ```
448
+
449
+ **Unicode output:**
450
+ ```
451
+ ┌───┐ ┌───┐
452
+ │ │ │ │
453
+ │ A │────►│ B │
454
+ │ │ │ │
455
+ └───┘ └───┘
456
+ ```
457
+
458
+ **ASCII output:**
459
+ ```
460
+ +---+ +---+
461
+ | | | |
462
+ | A |---->| B |
463
+ | | | |
464
+ +---+ +---+
465
+ ```
466
+
467
+ ### ASCII Options
468
+
469
+ ```typescript
470
+ renderMermaidASCII(diagram, {
471
+ useAscii: false, // true = ASCII, false = Unicode (default)
472
+ paddingX: 5, // Horizontal spacing between nodes
473
+ paddingY: 5, // Vertical spacing between nodes
474
+ boxBorderPadding: 1, // Padding inside node boxes
475
+ colorMode: 'auto', // 'none' | 'auto' | 'ansi16' | 'ansi256' | 'truecolor' | 'html'
476
+ theme: { ... }, // Partial<AsciiTheme> — override default colors
477
+ })
478
+ ```
479
+
480
+ ### ASCII XY Charts
481
+
482
+ XY charts render to ASCII with dedicated chart-drawing characters:
483
+
484
+ - **Bar charts** — `█` blocks (Unicode) or `#` (ASCII mode)
485
+ - **Line charts** — Staircase routing with rounded corners: `╭╮╰╯│─` (Unicode) or `+|-` (ASCII)
486
+ - **Multi-series** — Each series gets a distinct ANSI color from the theme's accent palette
487
+ - **Legends** — Automatically shown when multiple series are present
488
+ - **Horizontal charts** — Fully supported with categories on the y-axis
489
+
490
+ ---
491
+
492
+ ## API Reference
493
+
494
+ ### `renderMermaidSVG(text, options?): string`
495
+
496
+ Render a Mermaid diagram to SVG. Synchronous. Auto-detects diagram type.
497
+
498
+ **Parameters:**
499
+ - `text` — Mermaid source code
500
+ - `options` — Optional `RenderOptions` object
501
+
502
+ **RenderOptions:**
503
+
504
+ | Option | Type | Default | Description |
505
+ |--------|------|---------|-------------|
506
+ | `bg` | `string` | `#FFFFFF` | Background color (or CSS variable) |
507
+ | `fg` | `string` | `#27272A` | Foreground color (or CSS variable) |
508
+ | `line` | `string?` | — | Edge/connector color |
509
+ | `accent` | `string?` | — | Arrow heads, highlights |
510
+ | `muted` | `string?` | — | Secondary text, labels |
511
+ | `surface` | `string?` | — | Node fill tint |
512
+ | `border` | `string?` | — | Node stroke color |
513
+ | `font` | `string` | `Inter` | Font family |
514
+ | `transparent` | `boolean` | `false` | Render with transparent background |
515
+ | `padding` | `number` | `40` | Canvas padding in px |
516
+ | `nodeSpacing` | `number` | `24` | Horizontal spacing between sibling nodes |
517
+ | `layerSpacing` | `number` | `40` | Vertical spacing between layers |
518
+ | `componentSpacing` | `number` | `24` | Spacing between disconnected components |
519
+ | `thoroughness` | `number` | `3` | Crossing minimization trials (1-7, higher = better but slower) |
520
+ | `interactive` | `boolean` | `false` | Enable hover tooltips on XY chart bars and data points |
521
+
522
+ **XY Charts:** Diagrams starting with `xychart-beta` are auto-detected — no separate function needed. The `accent` color option drives the chart series color palette.
523
+
524
+ ### `renderMermaidSVGAsync(text, options?): Promise<string>`
525
+
526
+ Async version of `renderMermaidSVG()`. Same output, returns a `Promise<string>`. Useful in async server handlers or data loaders.
527
+
528
+ ### `renderMermaidASCII(text, options?): string`
529
+
530
+ Render a Mermaid diagram to ASCII/Unicode text. Synchronous.
531
+
532
+ **AsciiRenderOptions:**
533
+
534
+ | Option | Type | Default | Description |
535
+ |--------|------|---------|-------------|
536
+ | `useAscii` | `boolean` | `false` | Use ASCII instead of Unicode |
537
+ | `paddingX` | `number` | `5` | Horizontal node spacing |
538
+ | `paddingY` | `number` | `5` | Vertical node spacing |
539
+ | `boxBorderPadding` | `number` | `1` | Inner box padding |
540
+ | `colorMode` | `string` | `'auto'` | `'none'`, `'auto'`, `'ansi16'`, `'ansi256'`, `'truecolor'`, or `'html'` |
541
+ | `theme` | `Partial<AsciiTheme>` | — | Override default colors for ASCII output |
542
+
543
+ ### `parseMermaid(text): MermaidGraph`
544
+
545
+ Parse Mermaid source into a structured graph object (for custom processing).
546
+
547
+ ### `fromShikiTheme(theme): DiagramColors`
548
+
549
+ Extract diagram colors from a Shiki theme object.
550
+
551
+ ### `THEMES: Record<string, DiagramColors>`
552
+
553
+ Object containing all 15 built-in themes.
554
+
555
+ ### `DEFAULTS: { bg: string, fg: string }`
556
+
557
+ Default colors (`#FFFFFF` / `#27272A`).
558
+
559
+ ---
560
+
561
+ ## Attribution
562
+
563
+ The ASCII rendering engine is based on [mermaid-ascii](https://github.com/AlexanderGrooff/mermaid-ascii) by Alexander Grooff. We ported it from Go to TypeScript and extended it with:
564
+
565
+ - Sequence diagram support
566
+ - Class diagram support
567
+ - ER diagram support
568
+ - Unicode box-drawing characters
569
+ - Configurable spacing and padding
570
+
571
+ Thank you Alexander for the excellent foundation!
572
+
573
+ ---
574
+
575
+ ## License
576
+
577
+ MIT — see [LICENSE](LICENSE) for details.
578
+
579
+ ---
580
+
581
+ <div align="center">
582
+
583
+ Built with care by the team at [Craft](https://craft.do)
584
+
585
+ </div>