# 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 `, props: { filename: 'Counter.vue' } }) ``` ### MermaidBlockNode Component Progressive Mermaid diagram rendering with streaming updates. ```vue ``` ### MathBlockNode and MathInlineNode Components KaTeX-powered mathematical formula rendering for block and inline equations. ```vue ``` ### 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.