2.0 Migration Guide
Version 2.0 replaces the mdast pipeline with Comark, renders its compact document directly, and moves large rendering runtimes behind optional extensions. The Markdown component and its core display options remain familiar, but parser customization and rich-renderer configuration have changed.
Parser return value
When using @markmend/parser directly, parse() returns the document and
streaming completion information as one result. Replace direct document access
on the parse result:
// Before
const document = await parser.parse(markdown)
// 2.0
const { document, completion } = await parser.parse(markdown)getDocument() continues to return the latest successfully parsed document.
Custom completion functions may continue returning a string, or return
{ markdown, completion } to describe the syntax they completed.
Package changes
The main package remains:
pnpm add vue-stream-markdownInstall rich renderers separately:
pnpm add @stream-markdown/code
pnpm add @stream-markdown/math
pnpm add @stream-markdown/mermaid
pnpm add @stream-markdown/beautiful-mermaidPackage changes:
@markmend/astis replaced by@markmend/parser.@stream-markdown/htmlis removed; native HTML and custom tags are supported by the main package.- Beautiful Mermaid is no longer bundled with
@stream-markdown/mermaid. - Shiki, KaTeX, Mermaid, and Beautiful Mermaid types come from their corresponding extension packages.
Configure rich renderers
In 1.x, provider configuration was passed directly to Markdown:
<Markdown
:shiki-options="shikiOptions"
:katex-options="katexOptions"
:mermaid-options="mermaidOptions"
:cdn-options="cdnOptions"
/>In 2.0, create extension instances and pass them through extensions:
<script setup lang="ts">
import { beautifulMermaid } from '@stream-markdown/beautiful-mermaid'
import { code } from '@stream-markdown/code'
import { math } from '@stream-markdown/math'
import { mermaid } from '@stream-markdown/mermaid'
const extensions = {
code: code({ theme: ['github-light', 'github-dark'] }),
math: math(),
beautifulMermaid: beautifulMermaid(),
mermaid: mermaid(),
}
</script>
<template>
<Markdown :content="content" :extensions="extensions" />
</template>When both diagram extensions are configured, supported diagrams use Beautiful Mermaid and other diagram types fall back to Mermaid.
Replace parser APIs
| 1.x | 2.0 |
|---|---|
mdastOptions | parserOptions |
| Markmend preprocessing hooks | completion |
nodeRenderers keyed by mdast node type | components keyed by HTML/Comark tag |
components for built-in UI | uiComponents |
getMarkdownParser() | Removed |
getParsedNodes() | getDocument() |
getProcessedContent() | Removed |
The removed lifecycle hooks include normalize, preprocess, preprocessSteps, parseMarkdownIntoBlocks, postnormalize, and postprocess. Use a custom completion function for streaming syntax completion or a Comark plugin for document parsing behavior.
Custom completion
<script setup lang="ts">
function completion(markdown: string) {
return markdown.endsWith('**') ? markdown : markdown + '**'
}
</script>
<template>
<Markdown :content="content" :completion="completion" />
</template>Completion runs only in streaming mode. Static mode parses the original source.
Comark plugins
<script setup lang="ts">
import myPlugin from './my-comark-plugin'
const parserOptions = {
plugins: [myPlugin()],
}
</script>
<template>
<Markdown :content="content" :parser-options="parserOptions" />
</template>Replace custom renderers
In 1.x, nodeRenderers received mdast-oriented nodes. In 2.0, map the emitted tag name directly:
<script setup lang="ts">
import CustomHeading from './custom-heading.vue'
import GitHubCard from './github-card.vue'
const components = {
h2: CustomHeading,
github: GitHubCard,
}
</script>
<template>
<Markdown :content="content" :components="components" />
</template>The same mapping handles native Markdown elements and custom HTML-like tags.
If you previously passed built-in UI replacements through components, rename that prop:
<Markdown :ui-components="{ Button: CustomButton }" />Share configuration across messages
MarkdownProvider can supply extensions and theme defaults to a message list:
<MarkdownProvider :extensions="extensions">
<Markdown
v-for="message in messages"
:key="message.id"
:content="message.content"
/>
</MarkdownProvider>An individual Markdown can override a provider value when one message needs different behavior.
Migration checklist
- Install only the rich-renderer packages your application uses.
- Move Shiki, KaTeX, Mermaid, and CDN options into extension factories.
- Replace
mdastOptionswithparserOptionsorcompletion. - Replace
nodeRendererswith tag-basedcomponents. - Rename UI replacement
componentstouiComponents. - Replace parsed-node access with
getDocument(). - Remove
@stream-markdown/htmland any mdast compatibility code. - Import
katex/dist/katex.min.csswhen loading KaTeX locally. - Test custom tags, security rules, streaming-to-static transitions, and extension fallbacks.