reflex-mermaidjs
mermaid-js diagrams for Reflex: flowcharts, sequence, class, state, ER, gantt, mindmap, architecture, C4, sankey, kanban, venn, wardley, railroad and 30+ other diagram types, generated from text the way markdown is.
- Wraps mermaid 12.0.0 (ELK layout bundled), plus the tidy-tree layout and ZenUML plugins
- Every mermaid option as a typed prop:
theme,look(classic/handDrawn/neo),layout,security_level,theme_variables, rawconfig... appearance="dark"automatic dark themes (same behaviour as mermaid.live)- Pan & zoom (wheel, drag, double-click to fit) with a floating toolbar and optional dotted grid
- Events:
on_render,on_error,on_node_click,on_zoom_change - Python actions:
zoom_in,zoom_out,set_zoom,fit_view,reset_view,fullscreen,export_png,export_svg,copy_svg,get_svg - Icons: Iconify
logosandmdibundled, any other Iconify pack by name, Font Awesomefa:icons - KaTeX math (
$$...$$) in labels rx.markdownintegration:```mermaidfences become diagrams- Share helpers in pure Python:
mermaid_live_url,deserialize_state(mermaid.livepako:links),mermaid_ink_url,kroki_url - 36 diagram types of sample diagrams (
get_diagram_examples()), the same set mermaid.live offers
Installation
pip install reflex-mermaidjs
# or
uv add reflex-mermaidjs
Requires reflex>=0.9.11. npm dependencies (mermaid, plugins, icons) are installed automatically by Reflex.
Quick start
import reflex as rx
from reflex_mermaidjs import mermaid
def index() -> rx.Component:
return mermaid(
"""flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]""",
theme="forest",
)
app = rx.App()
app.add_page(index)
The diagram text can be passed positionally or as chart=, and can be a state var — the diagram re-renders when it changes.
Live editing with state, pan & zoom and events
import reflex as rx
from reflex_mermaidjs import mermaid, export_png, fit_view
class State(rx.State):
code: str = "sequenceDiagram\n Alice->>Bob: Hi Bob\n Bob-->>Alice: Hi Alice"
diagram_type: str = ""
error: str = ""
@rx.event
def set_code(self, value: str):
self.code = value
@rx.event
def rendered(self, event: dict):
self.diagram_type = event["diagram_type"]
self.error = ""
@rx.event
def failed(self, event: dict):
self.error = event["message"]
@rx.event
def clicked(self, event: dict):
return rx.toast.info(f"Clicked {event['node_id']}")
def index() -> rx.Component:
return rx.hstack(
rx.text_area(value=State.code, on_change=State.set_code.debounce(250), width="40%", rows="20"),
rx.vstack(
mermaid(
State.code,
id="diagram",
appearance=rx.color_mode_cond("light", "dark"),
pan_zoom=True,
grid=True,
node_click=True,
error_mode="keep-last",
on_render=State.rendered,
on_error=State.failed,
on_node_click=State.clicked,
height="600px",
width="100%",
),
rx.hstack(
rx.button("Fit", on_click=fit_view("diagram")),
rx.button("PNG", on_click=export_png("diagram", "diagram.png")),
rx.text(State.diagram_type),
),
width="60%",
),
)
Props
| Prop | Type | Description |
|---|---|---|
chart |
str |
Diagram definition (front matter and %%{init}%% directives are supported) |
config |
dict |
Raw MermaidConfig passed to mermaid.initialize |
theme |
default, base, dark, forest, neutral, neo, neo-dark, redux, redux-dark, redux-color, redux-dark-color, null |
Theme |
look |
classic, handDrawn, neo |
Visual look |
layout |
str |
dagre, elk, elk.stress, elk.force, elk.mrtree, elk.radial, elk.box, elk.rectpacking, tidy-tree... |
security_level |
strict, loose, antiscript, sandbox |
loose enables click callbacks and HTML labels |
theme_variables / theme_css |
dict / str |
Theme customisation (most useful with theme="base") |
font_family, font_size, hand_drawn_seed, dark_mode, html_labels, wrap, max_text_size, max_edges, deterministic_ids, log_level |
Same as the mermaid options | |
appearance |
light, dark |
With no explicit theme, dark uses the dark variant of each diagram type's default theme |
tidy_tree |
bool |
Register the tidy-tree layout (default True) |
zenuml |
bool |
Register ZenUML eagerly (it is auto-registered when the text starts with zenuml) |
font_awesome |
bool |
Load Font Awesome CSS for fa: icons (default True) |
icon_packs |
list[str | dict] |
Iconify packs. logos and mdi are bundled; other names load from jsDelivr; or {"name": ..., "url": ...} |
pan_zoom |
bool |
Wheel zoom + drag pan. The component fills its box, so give it a height (defaults to 480px) |
show_controls, controls_position |
bool, top-right... |
Floating toolbar (fit, zoom out, zoom in, 100%, fullscreen) |
min_zoom, max_zoom, zoom_step, max_fit_zoom |
float |
Zoom limits |
fit_on_render |
bool | "auto" |
auto fits on first render and when the diagram type/size changes a lot |
grid |
bool |
Dotted background grid (color via the --mermaid-grid-color CSS variable) |
center |
bool |
Center the SVG in static mode |
debounce |
int |
Debounce re-renders in ms |
error_mode |
inline, keep-last, none |
How parse errors are shown |
click_callbacks |
list[str] |
Callback names used in click node callback directives, routed to on_node_click |
node_click |
bool |
Emit on_node_click for any node click |
Events
| Event | Payload |
|---|---|
on_render |
{svg, diagram_type, render_id, render_ms} |
on_error |
{message, line, expected} |
on_node_click |
{node_id, callback, label, args} |
on_zoom_change |
{zoom, x, y} (debounced) |
Python actions
Any diagram with an id can be driven from event handlers or triggers. They return rx.call_script events:
from reflex_mermaidjs import zoom_in, zoom_out, set_zoom, fit_view, reset_view, fullscreen
from reflex_mermaidjs import export_png, export_svg, copy_svg, get_svg, get_png_data_url
rx.button("PNG", on_click=export_png("diagram", "diagram.png", scale=2, background="transparent"))
rx.button("Send SVG to Python", on_click=get_svg("diagram", State.receive_svg))
Markdown
from reflex_mermaidjs import markdown_with_mermaid, mermaid_component_map
markdown_with_mermaid(State.text, mermaid_props={"theme": "neutral"})
# or merge with your own map
rx.markdown(State.text, component_map={**mermaid_component_map(), "h1": my_h1})
Non-mermaid code fences keep the regular rx.code_block highlighting.
Sharing helpers
from reflex_mermaidjs import mermaid_live_url, mermaid_ink_url, kroki_url, deserialize_state
mermaid_live_url(code, {"theme": "dark"}) # https://mermaid.live/edit#pako:...
mermaid_ink_url(code, fmt="img", image_type="png") # server-rendered image
kroki_url(code, "svg")
state = deserialize_state("https://mermaid.live/edit#pako:eNp...") # {"code": ..., "mermaid": ...}
Icons
mermaid("""architecture-beta
group api(logos:aws-lambda)[API]
service db(logos:postgresql)[Database] in api
service server(logos:python)[Server] in api
db:L -- R:server""")
mermaid(
chart,
icon_packs=["logos", "mdi", "fa7-brands", {"name": "custom", "url": "https://example.com/icons.json"}],
)
Demo app
The mermaidjs_demo/ app is a mermaid.live-style editor built with this component:
- Live editor — code editor with line numbers, config tab (theme/look/layout/security selectors + JSON), all sample diagrams, history, share dialog (mermaid.live / mermaid.ink / kroki links, import a mermaid.live link, Python and Markdown snippets), PNG/SVG export, hand-drawn/grid/pan-zoom toggles, dark mode
- Gallery — every diagram type rendered live
- Features — themes, looks, layouts, theme variables from state, data-driven charts, events and actions, markdown, icons, math, ZenUML, error handling
- API — props table generated from the source
uv sync --all-groups
cd mermaidjs_demo
uv run reflex run
Development
uv sync --all-groups
uv run pytest # tests
uv run ruff check . # lint
uv run ruff format . # format
uv run bandit -c pyproject.toml -r . -ll # SAST
uv run reflex component build # generates .pyi stubs and builds dist/
The same checks run in CI on every push and pull request — see the Quality and Security workflows. Releases are tag-driven and documented in RELEASING.md; the security posture of the component is documented in SECURITY.md.
License
MIT © Ernesto Crespo
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file reflex_mermaidjs-0.1.0.tar.gz.
File metadata
- Download URL: reflex_mermaidjs-0.1.0.tar.gz
- Upload date:
- Size: 48.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11d8a65f3dbb3d160c6f29e7e1194c29b218addb1c1cc97292cb7aaa82b71578
|
|
| MD5 |
634a37b7eaaba336ea226401bbbca2b6
|
|
| BLAKE2b-256 |
aeadd7080532c530979347fcac1b9d7762b987898fa667c8cd48196a7c0529f9
|
File details
Details for the file reflex_mermaidjs-0.1.0-py3-none-any.whl.
File metadata
- Download URL: reflex_mermaidjs-0.1.0-py3-none-any.whl
- Upload date:
- Size: 46.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71ba6fe730fdce9e43e8dce6fdc9c772629e2a07e2ae57bf0a7a13fb834872db
|
|
| MD5 |
fb81ba9f0cd7cabcef7040fc8db04776
|
|
| BLAKE2b-256 |
3b68be574eed96ac5dbdffe2488d7453db2f8c2d3280ebfc2e176834ee586e6e
|