@fadedown/vue

Vue bindings and runtime helpers for streaming Markdown rendering.
524
Install
npm install @fadedown/vue
Latest Version:0.8.1
Vue:3
Last Updated:Sep 24, 2026
Links: GitHub  ·  npm
Maintainer: jannchie

@fadedown/vue

Vue bindings and runtime helpers for streaming Markdown rendering.

  • Frozen-prefix incremental rendering: per-chunk cost stays flat as the document grows.
  • Incomplete Markdown protection: tables, math, links, and inline markup never flash as raw text mid-stream.
  • Per-character fade-in that never re-animates already-rendered text.
  • Lazy Shiki (per-language grammar loading) and lazy KaTeX.

Installation

pnpm add @fadedown/vue vue

Usage

import {
  createStreamingMarkdownVNodes,
  createVNodeRendererComponent,
  splitContent,
} from '@fadedown/vue'
import '@fadedown/vue/styles.css'

createStreamingMarkdownVNodes() returns formattedContent, contentFinal, contentVNodes, and debouncedLoading.

Customizing the fade animation

The built-in animation is driven by CSS variables — override them on any ancestor:

.chat-message {
  --fadedown-animation-duration: 0.4s;
  --fadedown-animation-timing-function: ease-out;
  /* --fadedown-animation-name: your-own-keyframes; */
}

To integrate with an existing design system, replace the class entirely and bring your own animation CSS:

createStreamingMarkdownVNodes(content, loading, {
  fadeInClassName: 'message-appear',
})

The default code block UI is themeable the same way via --fadedown-code-* variables (bg, radius, font, toolbar-bg, toolbar-color, copy-hover-color).

Public API

  • addFadeInToVNodes(children, loading, options?)
  • configureMermaid(loader, config?) — opt into diagram rendering, e.g. configureMermaid(() => import('mermaid')); mermaid fences show their source while streaming and swap to SVG once valid
  • createSmoothedContent(source, options?) — typewriter smoothing: drains bursty chunks into a steady per-character reveal with proportional catch-up
  • createStreamingMarkdownVNodes(content, loading, options?) — options: splitMode, fadeInClassName
  • createVNodeRendererComponent(vnodes)
  • setCodeBlockComponent(component) — defaults to DefaultCodeBlock (language label + copy button)
  • setCustomComponents({ a: MyLink, img: MyImage, ... }) — replace rendered tags with your components; attributes arrive as props, content through the default slot
  • splitContent(message) / stripIncompleteMarkdown(message)

Notes

  • The package currently preserves the app's existing runtime behavior.
  • The heavy lifting lives in @fadedown/renderer, shared with the React package; this package contributes the Vue adapter, components, and composables.
  • fadeIn.ts adapts the framework-agnostic tree animation helper for Vue VNodes.
  • runtime.ts stays internal and owns the Markdown renderer instance plus lazy capability loading.
  • useStreamingMarkdown.ts contains the repeated Vue wiring that was previously duplicated inside app components.
  • Default animation styles are published via @fadedown/vue/styles.css.
  • KaTeX and Shiki are loaded on demand when matching content is detected.
  • The fade-in state is intentionally delayed for about 1 second after loading completes so the last rendered batch can still animate.
  • Raw HTML rendering uses browser DOM APIs internally, so client-side rendering is the safest path when your Markdown may contain raw HTML.

Version History

Version Released Vue License
0.8.1 ^3.5.0
0.8.0 ^3.5.0
0.7.0 ^3.5.0