npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@antdv-next/x-markdown

v0.1.4

Published

Vue 3 streaming-friendly, highly extensible, and high-performance Markdown renderer.

Readme

@antdv-next/x-markdown

Vue 3 streaming-friendly, highly extensible, and high-performance Markdown renderer.

✨ Features

Built on marked as the base Markdown renderer.

  • 🚀 Built for speed
  • 🤖 Streaming-friendly, a Markdown rendering solution for LLM/AI
  • ⬇️ Low-level compiler for parsing Markdown without long-term caching
  • ⚖️ Lightweight while implementing all supported Markdown styles
  • 🔐 Secure by default, no XSS attacks via DOMPurify
  • 🎨 Customizable components - replace any Markdown element with your own Vue components
  • 🔧 Rich plugin ecosystem
  • 😊 Compatible - 100% CommonMark compliant, 100% GFM compliant

Compatibility

| Edge | Firefox | Chrome | Safari | Opera | | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | >= 92 | >= 90 | >= 92 | >= 15.4 | >= 78 |

Supported Markdown Specifications

📦 Installation

npm install @antdv-next/x-markdown
yarn add @antdv-next/x-markdown
pnpm add @antdv-next/x-markdown

Example

<script setup>
import "@antdv-next/x-markdown/themes/index.css";
import "@antdv-next/x-markdown/themes/light.css";
import { XMarkdown } from "@antdv-next/x-markdown";

const content = `
# Hello World

### Welcome to XMarkdown!

- Item 1
- Item 2
- Item 3
`;
</script>

<template>
  <XMarkdown :content="content" />
</template>

Streaming Example

<script setup>
import "@antdv-next/x-markdown/themes/index.css";
import "@antdv-next/x-markdown/themes/light.css";
import { ref } from "vue";
import { XMarkdown } from "@antdv-next/x-markdown";

const content = ref("");
const streaming = ref({
  hasNextChunk: true,
  enableAnimation: true,
  tail: true,
});

// Simulate streaming
function onChunk(chunk) {
  content.value += chunk;
}
</script>

<template>
  <XMarkdown :content="content" :streaming="streaming" />
</template>

Styles

Breaking change: @antdv-next/x-markdown no longer imports styles automatically. Import the base styles manually, plus one optional theme stylesheet:

import "@antdv-next/x-markdown/themes/index.css";
import "@antdv-next/x-markdown/themes/light.css";

API

Props

| Property | Description | Type | Default | | ------------------------ | --------------------------------------------------- | ----------------------------------------- | --------------- | | content | Markdown content to render | string | - | | components | Map HTML nodes to custom Vue components | Record<string, Component> | - | | componentsProps | Extra props passed to custom components by tag name | Record<string, Record<string, unknown>> | - | | streaming | Streaming behavior config | StreamingOption | - | | config | Marked parse config | MarkedConfig | { gfm: true } | | className | Extra CSS class for root container | string | - | | style | Inline styles for root container | Record<string, string> | - | | paragraphTag | HTML tag for paragraphs | string | 'p' | | openLinksInNewTab | Add target="_blank" to all links | boolean | true | | protectCustomTagNewlines | Preserve newlines inside custom tags | boolean | true | | escapeRawHtml | Escape raw HTML as plain text | boolean | false | | debug | Enable debug mode | boolean | false |

Passing extra props to custom components

Custom components often need business data (theme, callbacks, etc.). Passing it via an inline wrapper function creates a new component on every render and forces the subtree to be re-created, losing internal state and hurting performance in streaming scenarios. Use componentsProps to pass extra props while keeping component references stable:

<script setup>
import { computed, ref } from "vue";
import { XMarkdown } from "@antdv-next/x-markdown";

const theme = ref("dark");
const components = { "custom-chart": CustomChart };
// Keep the reference stable — an inline object literal invalidates the render
// cache and re-parses the whole tree on every render.
const componentsProps = computed(() => ({
  "custom-chart": { theme: theme.value, onSelect },
}));
</script>

<template>
  <XMarkdown :components="components" :componentsProps="componentsProps" />
</template>

componentsProps is keyed by tag name. Its props are merged with the parsed HTML attributes and passed to the component:

  • On conflict componentsProps wins — a title in componentsProps overrides title="..." from the HTML.
  • class / className is the exception: both sides are concatenated, with the componentsProps class name first (merged into class).
  • Internally computed props — streamStatus, domNode, children (plus lang and block for code) — cannot be overridden and are ignored if present in componentsProps.

When componentsProps changes, the component receives a normal props update without being remounted. Like components, it takes part in the render cache, so passing an inline object literal invalidates that cache on every render and re-parses the whole tree — keep the reference stable (e.g. with computed) as shown above.

StreamingOption

| Field | Description | Type | Default | | ------------------------------ | ---------------------------------------------- | ------------------------------------ | ------- | | hasNextChunk | Whether more chunks are expected | boolean | false | | enableAnimation | Enable fade-in animation | boolean | true | | animationConfig | Animation options | AnimationConfig | - | | tail | Enable tail indicator | boolean \| TailConfig | false | | incompleteMarkdownComponentMap | Map incomplete fragments to loading components | Partial<Record<TokenType, string>> | - |

AnimationConfig

| Property | Description | Type | Default | | ------------ | ------------------- | -------- | ------------ | | fadeDuration | Duration in ms | number | 300 | | easing | CSS easing function | string | 'ease-out' |

TailConfig

| Property | Description | Type | Default | | --------- | -------------------------- | ----------- | ------- | | content | Content to display as tail | string | '▋' | | component | Custom tail component | Component | - |

Themes

Import base styles, theme styles, and set the theme class on the root:

<script setup>
import "@antdv-next/x-markdown/themes/index.css";
import "@antdv-next/x-markdown/themes/light.css";
</script>

<template>
  <XMarkdown class="x-markdown-light" content="# Hello" />
</template>

Available themes:

  • light.css - Light theme
  • dark.css - Dark theme

Plugins

Rich plugins available. See documentation for details.