# markstream-vue
## Introduction
**markstream-vue** is a high-performance Vue 3 Markdown renderer optimized for streaming scenarios and large documents. It provides progressive rendering capabilities with native support for incomplete or frequently updated tokenized Markdown, making it ideal for real-time chat applications, AI-generated content streams, and live documentation editors. The library leverages a streaming-first architecture that minimizes re-rendering and provides efficient DOM updates, ensuring smooth performance even when rendering lengthy documents character by character.
The component ecosystem includes Monaco-powered code blocks with streaming diff support, progressive Mermaid diagram rendering that updates as syntax becomes available, KaTeX math formula support with optional worker-based processing, inline HTML support with streaming-safe auto-closing, admonition blocks (note, warning, tip, danger), and a flexible node-based architecture allowing custom Vue components to be embedded directly in Markdown content. Built with TypeScript-first design, the library offers complete type definitions, IntelliSense support, and works out of the box in Vue 3 projects with zero configuration required. Optional peer dependencies (Monaco, Mermaid, KaTeX, Shiki) keep the core bundle lightweight while enabling rich features on demand.
## API Reference
### Installation and Setup
Install the package with optional peer dependencies for specific features.
```bash
# Core installation
pnpm add markstream-vue
# Optional: Enable all features
pnpm add shiki stream-markdown stream-monaco mermaid katex
```
```vue
```
### MarkdownRender Component
Main component that renders Markdown AST content with built-in node components.
```vue
```
### getMarkdown Parser Function
Creates a configured markdown-it-ts instance with required plugins and custom options.
```typescript
import { getMarkdown, parseMarkdownToStructure } from 'stream-markdown-parser'
import type { GetMarkdownOptions } from 'stream-markdown-parser'
// Basic usage
const md = getMarkdown('editor-123')
const result = md.render('# Hello World')
console.log(result) // HTML output
// With custom plugins and configuration
const options: GetMarkdownOptions = {
html: true,
linkify: true,
typographer: true,
plugin: [
[require('markdown-it-container'), 'warning'],
require('markdown-it-abbr')
],
apply: [
(md) => {
// Custom inline rule
md.inline.ruler.before('escape', 'custom', (state, silent) => {
// Custom parsing logic
return false
})
}
],
i18n: {
'common.copy': 'Copy Code',
'common.expand': 'Expand'
}
}
const customMd = getMarkdown('editor-custom', options)
const html = customMd.render('# Custom Parser')
```
### parseMarkdownToStructure Function
Converts Markdown strings into AST nodes for direct rendering control.
```typescript
import { getMarkdown, parseMarkdownToStructure } from 'stream-markdown-parser'
import type { ParseOptions, ParsedNode } from 'stream-markdown-parser'
const md = getMarkdown()
const markdown = `# Title
This is a paragraph with **bold** and *italic* text.
\`\`\`javascript
const x = 42
\`\`\`
`
// Basic parsing
const nodes: ParsedNode[] = parseMarkdownToStructure(markdown, md)
console.log(nodes)
// Output: Array of node objects with type, children, props, etc.
// With transformation hooks
const parseOptions: ParseOptions = {
preTransformTokens(tokens) {
// Modify tokens before processing
return tokens.map(token => {
if (token.type === 'fence' && token.info === 'typescript') {
token.info = 'ts' // Normalize language
}
return token
})
},
postTransformNodes(nodes) {
// Modify nodes after parsing
return nodes.map(node => {
if (node.type === 'code_block') {
node.props = { ...node.props, theme: 'dracula' }
}
return node
})
}
}
const transformedNodes = parseMarkdownToStructure(markdown, md, parseOptions)
```
```vue
```
### setCustomComponents Function
Registers custom node renderers to override default components.
```vue
```
```typescript
// app.ts - Register custom components
import { setCustomComponents, removeCustomComponents } from 'markstream-vue'
import CustomImageNode from './CustomImageNode.vue'
import CustomCodeBlock from './CustomCodeBlock.vue'
import CustomLinkNode from './CustomLinkNode.vue'
// Scoped registration (recommended)
setCustomComponents('docs', {
image: CustomImageNode,
code_block: CustomCodeBlock,
link: CustomLinkNode
})
// Global registration (affects all MarkdownRender instances without custom-id)
setCustomComponents(undefined, {
image: CustomImageNode
})
// Remove custom components when no longer needed
removeCustomComponents('docs')
```
```vue
```
### CodeBlockNode Component
Monaco-powered code block with streaming, diff markers, and interactive toolbar.
```vue
```
### MarkdownCodeBlockNode Component
Lightweight syntax highlighting using Shiki instead of Monaco for SSR-friendly scenarios.
```vue
```
### MathBlockNode and MathInlineNode Components
KaTeX-powered mathematical formula rendering for block and inline equations.
```vue
The famous equation
relates energy and mass.
The set of real numbers
is uncountable.
```
### AdmonitionNode Component
Styled alert/callout blocks with collapsible support for notes, warnings, tips, and danger messages.
```vue
```
Supported admonition types: `note`, `info`, `tip`, `warning`, `danger`, `caution`, `error`.
### HtmlInlineNode Component
Renders inline HTML content with streaming support and auto-closing for incomplete tags.
```vue
```
The component handles streaming scenarios where HTML tags may be incomplete, showing loading states and auto-closing tags when appropriate.
### Global Configuration Functions
Configure default options for math rendering and internationalization.
```typescript
import {
setDefaultMathOptions,
setDefaultI18nMap,
registerMarkdownPlugin,
clearRegisteredMarkdownPlugins
} from 'markstream-vue'
import { setLanguageIconResolver } from 'markstream-vue'
// Configure KaTeX defaults globally
setDefaultMathOptions({
displayMode: false,
throwOnError: false,
errorColor: '#cc0000',
macros: {
'\\RR': '\\mathbb{R}',
'\\CC': '\\mathbb{C}'
},
trust: true
})
// Configure i18n translations
setDefaultI18nMap({
'common.copy': 'Copy Code',
'common.copied': 'Copied!',
'common.expand': 'Expand',
'common.collapse': 'Collapse',
'common.preview': 'Preview'
})
// Custom language icon resolver
setLanguageIconResolver((lang: string) => {
const icons: Record = {
typescript: '📘',
javascript: '📙',
python: '🐍',
rust: '🦀',
go: '🔵'
}
return icons[lang] || '📄'
})
```
### Feature Enablers
Enable optional heavy dependencies on demand.
```typescript
import { enableKatex, enableMermaid, disableKatex, disableMermaid, isKatexEnabled, isMermaidEnabled } from 'markstream-vue'
// Enable KaTeX math rendering
enableKatex()
// Enable Mermaid diagram rendering
enableMermaid()
// Check if features are enabled
if (isKatexEnabled()) {
console.log('KaTeX is ready')
}
if (isMermaidEnabled()) {
console.log('Mermaid is ready')
}
// Disable features when no longer needed
disableKatex()
disableMermaid()
```
### Vue Plugin Installation
Register all components globally using Vue plugin system.
```typescript
import { createApp } from 'vue'
import { VueRendererMarkdown } from 'markstream-vue'
import App from './App.vue'
const app = createApp(App)
// Install plugin with options
app.use(VueRendererMarkdown, {
getLanguageIcon: (lang: string) => {
return lang === 'vue' ? '💚' : undefined
},
mathOptions: {
displayMode: false,
throwOnError: false,
macros: {
'\\vec': '\\mathbf{#1}'
}
}
})
app.mount('#app')
```
```vue
```
## Summary
**markstream-vue** excels in scenarios requiring real-time Markdown rendering, such as AI chat interfaces with streaming responses, collaborative documentation editors, live preview panes in IDEs, and progressive content loading in blogs or wikis. The library's streaming-first architecture ensures smooth character-by-character updates without flickering or layout shifts, while viewport priority optimization defers expensive operations like Monaco editor initialization and Mermaid diagram rendering until elements enter the viewport. The comprehensive component system supports tables, formulas, emoji, checkboxes, footnotes, admonitions, inline HTML with auto-closing, and custom HTML blocks, making it suitable for technical documentation, academic papers, and feature-rich content management systems.
Integration patterns include direct component usage for simple cases, pre-parsed node rendering for server-side processing or content transformation pipelines, custom component registration for brand-specific UI overrides, and worker-based parsing for offloading heavy computation. The library works seamlessly with Vue 3 ecosystems including Vite, Nuxt, and VitePress, with built-in SSR safety guards and optional client-only rendering for browser-dependent features. CSS architecture uses layered imports compatible with Tailwind and UnoCSS, while the custom-id scoping system prevents style conflicts in multi-instance applications. TypeScript-first design provides complete type safety across the entire API surface, making it easy to extend parsers, create custom node renderers, and integrate with existing Vue applications. Recent additions include HtmlInlineNode for streaming inline HTML with auto-closing support, AdmonitionNode for styled alert blocks with collapsible support, enhanced Mermaid security with strict mode, and improved math parsing with better mid-state handling.