vue-mdr
| Install | |
|---|---|
npm install vue-mdr |
|
| Latest Version: | 0.1.3 |
| Vue: | 3 |
| License: | ISC |
| Last Updated: | Apr 30, 2026 |
| Links: | GitHub · npm |
VueMarkdownRenderer
A config-driven, high-performance Markdown renderer for Vue, designed for LLM streaming, rich code blocks, and embedded visual components.
Core Idea
Unlike traditional Markdown components that rely on many reactive props, VueMarkdownRenderer uses a single static configuration to define rendering behavior.
const MarkdownRenderer = createMarkdownRenderer(config);
- Rendering capabilities are defined once
- The returned renderer component is pure and predictable
- Avoids the mental overhead of “is this prop reactive?”
This design is intentional: 99% of Markdown rendering scenarios do not require runtime mutation of render rules.
Installation
npm install vue-mdr
Basic Usage
import { createMarkdownRenderer } from "vue-mdr";
export const MarkdownRenderer = createMarkdownRenderer({
// configuration here
});
<template>
<MarkdownRenderer :source="markdownText" theme="light" />
</template>
Full Configuration Example
Below is a complete example matching the latest API design.
import { createMarkdownRenderer } from "vue-mdr";
import "katex/dist/katex.min.css";
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";
import type { Plugin } from "unified";
import {
BarChart,
CodeBlockRenderer,
MermaidRenderer,
EchartRenderer,
Placeholder,
} from "./components";
export const MarkdownRenderer = createMarkdownRenderer({
/**
* Custom Vue components rendered via `component-json` blocks
*/
componentsMap: {
BarChart,
Placeholder,
// The rendering of HTML tags can also be overridden using this componentMap
// !However, besides `pre`, which already uses it built-in
a: ARenderer,
img: ImageRenderer,
},
/**
* Custom code block renderer
*/
codeBlock: {
renderer: CodeBlockRenderer,
},
/**
* ECharts support
*/
echart: {
renderer: EchartRenderer,
placeholder: Placeholder,
},
/**
* Mermaid diagrams
*/
mermaid: {
renderer: MermaidRenderer,
},
/**
* Markdown / HTML plugins
*/
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex as unknown as Plugin],
/**
* built-in remarkRehype plugin options
*/
remarkRehypeOptions: {
allowDangerousHtml: true,
},
/**
* built-in rehypeSanitize plugin custom schema
*/
rehypeSanitizeSchema: {
attributes: {
"*": ["className", "style"],
},
},
});
Design Philosophy
1. Static Configuration over Reactive Props
createMarkdownRenderer({
mermaid: { renderer },
echart: { renderer },
codeBlock: { renderer },
});
- No runtime mutation
- No watchers
- No ambiguous reactivity expectations
The renderer is configured, not controlled.
2. Capability-based Rendering
Each feature is opt-in:
| Feature | Config Key |
|---|---|
| Code blocks | codeBlock |
| Mermaid | mermaid |
| ECharts | echart |
| Vue components | componentsMap |
| LaTeX | remarkPlugins / rehypePlugins |
If you don’t configure it, it doesn’t exist.
Custom Code Block Rendering
Your CodeBlockRenderer receives:
interface Props {
highlightVnode: VNode;
language: string;
}
This allows you to implement:
- Copy buttons
- Language labels
- Custom headers
- Animations
- Streaming-friendly UI
codeBlock: {
renderer: CodeBlockRenderer,
}
Rendering Vue Components (component-json)
```component-json {"placeholder": "Placeholder"}
{
"type": "BarChart",
"props": {
"chartData": {
"categories": ["A", "B", "C"],
"seriesData": [10, 20, 30]
}
}
}
```
{"type":"BarChart","props":{"chartData":{"categories":["type1","type2","type3","type4","type5","type6","type7","type8","type9","type10","type11","type12","type13","type14","type15","type16","type17","type18","type19","type20"],"seriesData":[100,200,150,180,120,130,170,160,190,210,220,140,125,155,165,175,185,195,205,215]}}}
Rendering ECharts
```echarts
{
"title": {
"text": "数据对比趋势变化",
"left": "center"
},
"tooltip": {
"trigger": "axis",
"axisPointer": {
"type": "cross",
"crossStyle": { "color": "#999" }
},
"formatter": "{b}<br/>{a0}: {c0}"
},
"legend": {
"data": ["本期"],
"top": "bottom"
},
"grid": {
"left": "3%",
"right": "4%",
"bottom": "10%",
"containLabel": true
},
"xAxis": [
{
"type": "category",
"data": ["xxx", "zzz"],
"axisPointer": { "type": "shadow" }
}
],
"yAxis": [
{
"type": "value",
"name": "数值",
"min": 0,
"axisLabel": { "formatter": "{value}" }
}
],
"series": [
{
"name": "本期",
"type": "bar",
"data": [5061.1429, 504.8844],
"itemStyle": { "color": "#3ba272" }
}
]
}
```
Configuration:
echart: {
renderer: EchartRenderer,
placeholder: Placeholder,
}
{
"title": {
"text": "数据对比趋势变化",
"left": "center"
},
"tooltip": {
"trigger": "axis",
"axisPointer": {
"type": "cross",
"crossStyle": { "color": "#999" }
},
"formatter": "{b}<br/>{a0}: {c0}"
},
"legend": {
"data": ["本期"],
"top": "bottom"
},
"grid": {
"left": "3%",
"right": "4%",
"bottom": "10%",
"containLabel": true
},
"xAxis": [
{
"type": "category",
"data": ["xxx", "zzz"],
"axisPointer": { "type": "shadow" }
}
],
"yAxis": [
{
"type": "value",
"name": "数值",
"min": 0,
"axisLabel": { "formatter": "{value}" }
}
],
"series": [
{
"name": "本期",
"type": "bar",
"data": [5061.1429, 504.8844],
"itemStyle": { "color": "#3ba272" }
}
]
}
Mermaid Diagrams
```mermaid
sequenceDiagram
Alice->>Bob: Hello
Bob-->>Alice: Hi!
```
mermaid: {
renderer: MermaidRenderer,
}
sequenceDiagram
Alice->>Bob: Hello
Bob-->>Alice: Hi!
LaTeX Support
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex],
$$ \begin{align} \nabla \times \vec{\mathbf{B}} -, \frac1c, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \ \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \ \nabla \times \vec{\mathbf{E}}, +, \frac1c, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \ \nabla \cdot \vec{\mathbf{B}} & = 0 \end{align} $$
Related Packages
Streaming markdown output, Useful for text streams like LLM outputs.
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.1.3 | ^3.2.0 | ISC | |
| 0.1.2 | ^3.2.0 | ISC | |
| 0.1.1 | ^3.2.0 | ISC | |
| 0.1.0 | ^3.2.0 | ISC | |
| 0.0.16 | ^3.2.0 | ISC | |
| 0.0.15 | ^3.2.0 | ISC | |
| 0.0.14 | ^3.2.0 | ISC | |
| 0.0.13 | ^3.2.0 | ISC | |
| 0.0.12 | ^3.2.0 | ISC | |
| 0.0.11 | ^3.2.0 | ISC | |
| 0.0.10 | ^3.2.0 | ISC | |
| 0.0.9 | ^3.2.0 | ISC | |
| 0.0.8 | ^3.2.0 | ISC | |
| 0.0.7 | ^3.2.0 | ISC | |
| 0.0.6 | ^3.2.0 | ISC | |
| 0.0.5 | ^3.2.0 | ISC | |
| 0.0.4 | ^3.5.13 | ISC | |
| 0.0.3 | ^3.5.13 | ISC | |
| 0.0.2 | ^3.5.13 | ISC | |
| 0.0.1 | ^3.5.13 | ISC | |
| 0.0.0 | ^3.5.13 | ISC |
Pre-releases (5)
| Version | Released | Vue | License |
|---|---|---|---|
| 0.0.3-alpha-5 | ^3.5.13 | ISC | |
| 0.0.3-alpha-4 | ^3.5.13 | ISC | |
| 0.0.3-alpha-3 | ^3.5.13 | ISC | |
| 0.0.3-alpha-2 | ^3.5.13 | ISC | |
| 0.0.3-alpha-1 | ^3.5.13 | ISC |