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 Python 3.11+ and reflex>=0.10.0 (Reflex 0.10 dropped Python 3.10). 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
Metadata
Release files for reflex-mermaidjs 0.2.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 | Provenance | |
|---|---|---|---|---|
| reflex_mermaidjs-0.2.0.tar.gz | 48.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| reflex_mermaidjs-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 94.7 kB
Release files / reflex_mermaidjs-0.2.0.tar.gz
| Download URL | reflex_mermaidjs-0.2.0.tar.gz |
|---|---|
| Size | 48.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
012117b2b3209e0c4b8aaefcced4b3f6b134e33dcc9fb668b016ecb0cf107a28
|
|
BLAKE2b-256 checksum How to use checksums |
c2e67dd79a568b45c9bc0ca11eade7a626b93bd10c2c6dbf4e8f9c57f5dc4a1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","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}
|
Release files / reflex_mermaidjs-0.2.0-py3-none-any.whl
| Download URL | reflex_mermaidjs-0.2.0-py3-none-any.whl |
|---|---|
| Size | 46.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
26171d8ea672346c3a1d79897f30c277db8ea7c13db85c8e1f4eba46b3193019
|
|
BLAKE2b-256 checksum How to use checksums |
b066d48f029acf97a2878db961824e4472f350229b967c7d31811b33fe38678c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","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}
|
Security for reflex-mermaidjs 0.2.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.