Vue 2 Installation
Install markstream-vue2 with pnpm, npm or yarn.
pnpm add markstream-vue2
# or
npm install markstream-vue2
# or
yarn add markstream-vue2Requirements
markstream-vue2 requires:
- Vue 2.6.14+ (Vue 2.7 is recommended for better TypeScript support)
- @vue/composition-api (if using Vue 2.6.x)
Composition API compatibility (Vue 2.6 / 2.7 / 3.x)
| Vue version | Composition API availability | What to install | How to import |
|---|---|---|---|
| 2.6.x | Not built-in | @vue/composition-api | import { ref, computed, defineComponent } from '@vue/composition-api' |
| 2.7.x | Built-in | None | import { ref, computed, defineComponent } from 'vue' |
| 3.x | Built-in | None | import { ref, computed, defineComponent } from 'vue' |
Notes:
- For Vue 2.6.x, you must install and register the plugin (
Vue.use(@vue/composition-api)), otherwise you will get runtime errors. - For Vue 2.7.x, do not install
@vue/composition-api— it is already included in Vue 2.7. - For Vue 3.x, use markstream-vue (not markstream-vue2).
Quick start by version (dependencies + entry)
Vue 2.6.x
Dependencies:
pnpm add markstream-vue2 vue@2.6.14 vue-template-compiler@2.6.14 @vue/composition-apiApp entry:
import VueCompositionAPI from '@vue/composition-api'
import MarkdownRender, { VueRendererMarkdown } from 'markstream-vue2'
import Vue from 'vue'
import 'markstream-vue2/index.css'
Vue.use(VueCompositionAPI)
Vue.use(VueRendererMarkdown)
new Vue({
render: h => h(MarkdownRender, { props: { content: '# Vue 2.6' } }),
}).$mount('#app')Composition API usage in components:
import { defineComponent, ref } from '@vue/composition-api'Example in this repo:
playground-vue2-cli(Vue 2.6 + Vue CLI / Webpack 4)
Path and start command:
pnpm -C playground-vue2-cli devFrom repo root you can also run:
pnpm play:vue2-cliVue 2.7.x
Dependencies:
pnpm add markstream-vue2 vue@2.7.16 vue-template-compiler@2.7.16App entry:
import MarkdownRender, { VueRendererMarkdown } from 'markstream-vue2'
import Vue from 'vue'
import 'markstream-vue2/index.css'
Vue.use(VueRendererMarkdown)
new Vue({
render: h => h(MarkdownRender, { props: { content: '# Vue 2.7' } }),
}).$mount('#app')Composition API usage in components:
import { defineComponent, ref } from 'vue'Example in this repo:
playground-vue2(Vue 2.7 + Vite)
Path and start command:
pnpm -C playground-vue2 devFrom repo root you can also run:
pnpm play:vue2Vue 3.x (use markstream-vue)
Dependencies:
pnpm add markstream-vue vue@^3App entry:
import MarkdownRender from 'markstream-vue'
import { createApp, h } from 'vue'
import 'markstream-vue/index.css'
createApp({
render: () => h(MarkdownRender, { content: '# Vue 3' }),
}).mount('#app')If your workspace also installs Vue 3, make sure vue-demi targets Vue 2:
pnpm vue-demi-switch 2If you cannot run vue-demi-switch (or want a per-app fix), alias vue-demi to the Vue 2 build in your bundler config. This avoids errors like defineComponent is not a function:
// vue.config.js / webpack config
module.exports = {
configureWebpack: {
resolve: {
alias: {
'vue-demi$': 'vue-demi/lib/v2/index.cjs',
},
},
},
}Optional Peer Dependencies
markstream-vue2 supports various features through optional peer dependencies. Install only what you need:
| Feature | Required Packages | Install Command |
|---|---|---|
Shiki code blocks (MarkdownCodeBlockNode) | shiki, stream-markdown | pnpm add shiki stream-markdown |
| Monaco Editor (full code block features) | stream-monaco | pnpm add stream-monaco |
| Mermaid Diagrams | mermaid | pnpm add mermaid |
| D2 Diagrams | @terrastruct/d2 | pnpm add @terrastruct/d2 |
| Math Rendering (KaTeX) | katex | pnpm add katex |
Vue 2.6.x Setup
If you're using Vue 2.6.x, you need to install and configure @vue/composition-api:
pnpm add @vue/composition-apiThen in your app entry:
import VueCompositionAPI from '@vue/composition-api'
import Vue from 'vue'
Vue.use(VueCompositionAPI)Using Composition API in Vue 2.6 components:
import { defineComponent, ref } from '@vue/composition-api'Vue 2.7.x Setup (no plugin required)
Vue 2.7 has Composition API built-in. Do not install @vue/composition-api.
import { defineComponent, ref } from 'vue'Feature loaders (Mermaid / KaTeX / D2)
After installing optional peers, the default loaders are already enabled. Only call these helpers if you disabled them earlier or need a custom loader (for example, a CDN build):
import { enableD2, enableKatex, enableMermaid } from 'markstream-vue2'
// optional: re-enable or override loaders
enableMermaid()
enableKatex()
enableD2()Also remember required CSS (when the feature is used):
import 'markstream-vue2/index.css'
import 'katex/dist/katex.min.css'Monaco (stream-monaco) does not require a separate CSS import.
Note: markstream-vue2/index.css is scoped under an internal .markstream-vue2 container to reduce global style conflicts. MarkdownRender renders inside that container by default. If you render node components standalone, wrap them with <div class="markstream-vue2">...</div>.
Vue CLI (Webpack 4) Notes
Vue CLI 4 uses Webpack 4 by default, and Webpack 4 doesn't support package.json#exports. That commonly breaks:
import 'markstream-vue2/index.css'import('mermaid')- Vite-style worker imports:
?worker/?worker&inline
Recommended setup (see playground-vue2-cli):
- Import CSS via the real file path (no
exportsneeded):
import 'markstream-vue2/dist/index.css'- For Mermaid, prefer the CDN global build (avoids Webpack 4
exports/ ESM chains):
<!-- public/index.html -->
<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>- For KaTeX / Mermaid workers, prefer CDN workers to avoid Webpack 4 worker limitations:
import { createKaTeXWorkerFromCDN, createMermaidWorkerFromCDN, setKaTeXWorker, setMermaidWorker } from 'markstream-vue2'
const { worker: katexWorker } = createKaTeXWorkerFromCDN({
mode: 'classic',
katexUrl: 'https://cdn.jsdelivr.net/npm/katex@0.16.25/dist/katex.min.js',
mhchemUrl: 'https://cdn.jsdelivr.net/npm/katex@0.16.25/dist/contrib/mhchem.min.js',
})
if (katexWorker)
setKaTeXWorker(katexWorker)
const { worker: mermaidWorker } = createMermaidWorkerFromCDN({
mode: 'classic',
mermaidUrl: 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js',
})
if (mermaidWorker)
setMermaidWorker(mermaidWorker)If you want to keep using subpath imports like markstream-vue2/index.css, add resolve.alias mappings in vue.config.js (see playground-vue2-cli/vue.config.js).
Code blocks: prefer stream-markdown override
In Webpack 4, Monaco integration (stream-monaco) is prone to edge cases (worker resolution, ESM entrypoints, service registration, and Shiki/TextMate regex engine init issues). If your goal is “render code blocks with highlighting”, the most reliable approach is:
- Install Shiki renderer deps:
pnpm add shiki stream-markdown- Override
code_blockto useMarkdownCodeBlockNode(or your own component):
import { MarkdownCodeBlockNode, setCustomComponents } from 'markstream-vue2'
setCustomComponents({ code_block: MarkdownCodeBlockNode })- Webpack config pitfalls:
- If you use
webpack.IgnorePluginfor optional dependencies, ensurestream-markdownis not ignored. stream-markdownis ESM-only. In a CJSvue.config.js,require.resolve('stream-markdown')can fail even when installed. Use a filesystem fallback (checknode_modules/stream-markdown) and alias it todist/index.js. Seeplayground-vue2-cli/vue.config.js.
If you're in a monorepo/workspace (common with pnpm), make sure your app uses a single Vue 2 runtime instance. Otherwise you may see runtime warnings like: provide() can only be used inside setup() / onMounted is called when there is no active component instance (caused by duplicated Vue copies and mismatched Composition API context). Fix this by pinning vue$ to your project's Vue 2 runtime in Webpack (see playground-vue2-cli/vue.config.js).
Tailwind CSS Support
If your app uses Tailwind and you want to avoid duplicate utility CSS, import the Tailwind-ready output instead:
import 'markstream-vue2/index.tailwind.css'And include the extracted class list in tailwind.config.js:
module.exports = {
content: [
'./src/**/*.{js,ts,vue}',
require('markstream-vue2/tailwind'),
],
}This approach ensures that Tailwind includes all the utility classes used by markstream-vue2 in its purge process, resulting in a smaller final bundle size.
Troubleshooting (Common Runtime Errors)
defineComponent is not a function
Cause: vue-demi is in Vue 3 mode but the app runs Vue 2.x. Fix (pick one):
- Run
pnpm vue-demi-switch 2. - Or alias
vue-demi$tovue-demi/lib/v2/index.cjsin your bundler config (see above).
provide() can only be used inside setup() / onMounted is called when there is no active component instance
Cause: duplicate Vue 2 runtime instances in monorepo/pnpm workspace. Fix: ensure a single Vue 2 instance is used across the app and linked packages:
- Alias
vue$to your app's Vue 2 runtime (seeplayground-vue2-cli/vue.config.js). - In pnpm workspaces, add
overridesforplayground-vue2-cli>vueto pin Vue 2.
Vue packages version mismatch
Cause: vue and vue-template-compiler versions differ. Fix: align them (e.g. both 2.6.14 or both 2.7.16). In pnpm, you can use packageExtensions or overrides.
Cannot read properties of undefined (reading 'props')
Cause: Vue 2.6 + Composition API missing _setupProxy patch, or Composition API not installed. Fix:
- Ensure
@vue/composition-apiis installed andVue.use(VueCompositionAPI)is executed before using markstream-vue2. - Upgrade to the latest
markstream-vue2build in this repo (it patches_setupProxyfor Vue 2.6).
Quick Install: All Features
To enable all features at once:
pnpm add shiki stream-markdown stream-monaco mermaid @terrastruct/d2 katex
# or
npm install shiki stream-markdown stream-monaco mermaid @terrastruct/d2 katexFeature Details
Code Syntax Highlighting
Requires both shiki and stream-markdown:
pnpm add shiki stream-markdownThese packages power the Shiki-based MarkdownCodeBlockNode. To use Shiki inside MarkdownRender, override the code_block renderer (or render MarkdownCodeBlockNode directly).
import MarkdownRender, { MarkdownCodeBlockNode, setCustomComponents } from 'markstream-vue2'
setCustomComponents({ code_block: MarkdownCodeBlockNode })Monaco Editor
For full code block functionality (copy button, font size controls, expand/collapse):
pnpm add stream-monacoWithout stream-monaco, code blocks will render but interactive buttons may not work.
Mermaid Diagrams
For rendering Mermaid diagrams:
pnpm add mermaidD2 Diagrams
For rendering D2 diagrams:
pnpm add @terrastruct/d2KaTeX Math Rendering
For math formula rendering:
pnpm add katexAlso import the KaTeX CSS in your app entry:
import 'katex/dist/katex.min.css'Quick Test
Import and render a simple markdown string:
<script>
import MarkdownRender from 'markstream-vue2'
import 'markstream-vue2/index.css'
export default {
components: {
MarkdownRender
},
data() {
return {
md: '# Hello from markstream-vue2!'
}
}
}
</script>
<template>
<MarkdownRender :content="md" />
</template>Using with Composition API (Vue 2.7+)
If you're using Vue 2.7 or have @vue/composition-api installed:
<script>
import { defineComponent, ref } from '@vue/composition-api' // or 'vue' for 2.7
import MarkdownRender from 'markstream-vue2'
import 'markstream-vue2/index.css'
export default defineComponent({
components: {
MarkdownRender
},
setup() {
const md = ref('# Hello from markstream-vue2 with Composition API!')
return { md }
}
})
</script>
<template>
<MarkdownRender :content="md" />
</template>TypeScript Support
markstream-vue2 includes TypeScript definitions. For Vue 2.6.x, you may need to configure your tsconfig.json:
{
"compilerOptions": {
"types": ["@vue/composition-api"]
}
}For Vue 2.7+, types are included automatically.