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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@markdown-vue/mdv

v1.0.28

Published

Markdown-Vue (MDV) lets you write Vue-style components directly inside Markdown files.

Readme

Markdown-Vue (MDV) Documentation (Updated)

Overview

Markdown-Vue (MDV) lets you write Vue-style components directly inside Markdown files. Each .md file can contain:

  • Regular Markdown content
  • Vue-style templates and components (standard HTML/Vue tags)
  • YAML frontmatter for metadata
  • Inline <script> and <style> blocks
  • A small inline component shorthand for short components

This keeps the source human-readable while enabling Vue integration.


Core principles

  • Template-first: Markdown is the base template; sprinkle Vue/HTML where needed.
  • Standard HTML / Vue tags: Use normal HTML elements and Vue component tags (<div>, <section>, <UserBadge>, etc.). MDV follows standard Vue/HTML semantics.
  • Inline component shorthand: MDV provides a concise inline shorthand for simple, content-driven components.

Syntax reference

Block elements

Use standard HTML elements and Vue component tags. Attributes follow Vue syntax (v-for, v-if, :prop, @click, etc.).

Example:

<div class="card">
  # Title inside the card
  <p>This paragraph lives inside the div</p>
</div>

Interpolation

Mustache interpolation ({{ }}) works anywhere in the template.

Hello, {{ user.name }}

Inline component syntax

MDV supports a compact inline component shorthand in two forms:

  • Slot content:
[text]{ ::ComponentName }
  • Dynamic/default-slot expression:
:[user.name]{ ::UserBadge }

Props, directives, and bindings are passed inside the braces:

[Click me]{ ::Button :to="user.url" @click="onClick(user)" v-if="user.active" }

Notes:

  • The inline shorthand forms [text]{ ::Component ... } and :[expr]{ ::Component } are the only MDV-specific shorthands.
  • For multiple named slots or complex layouts prefer full component tags (<MyComponent>...</MyComponent>).

Loops

Use Vue's v-for on any element or component. Always include :key.

Example with HTML tags:

<ul>
  <li v-for="(user, i) in users" :key="user.id || i">
    <UserBadge>{{ user.name }}</UserBadge>
  </li>
</ul>

Inline shorthand in loops:

:[item]{ v-for="item in items" :key="item.id || itemIndex" }

The : inline form places the evaluated expression into the default slot for the inline component.

Notes:

  • Use :key with every v-for.
  • Prefer inline loops for small, simple items.

Dynamic tables

MDV supports dynamic rows inside standard Markdown tables using a { rows } placeholder. Header is normal Markdown; rows are injected where { rows } appears. A fallback row is optional.

Example:

| id            | name | action |
| ------------- | ---- | ------ |
| No item found |

{ rows }

How it works:

  • { rows } is replaced by rendered rows generated from your data source.
  • If the data is empty and you provided a fallback row (like | No item found |), that row is shown.
  • Rows may contain inline components or full HTML/Vue tags.

Simple conceptual example:

<!-- body -->

| id            | name | action |
| ------------- | ---- | ------ |
| No item found |

{ rows }

<script setup>
const rows = items.map(item => `| ${item.id} | ${item.name} | [Edit]{ ::EditButton :id="${item.id}" } |`).join('\\n')
</script>

Notes:

  • Fallback row is optional.
  • Keep header as normal Markdown.

Scripts and Styles

You may include <script> and <style> blocks inside .md files. Prefer <script setup>.

Script example:

<script setup lang="ts">
import UserBadge from './UserBadge.vue'
import { ref } from 'vue'

const users = ref([
  { id: 1, name: 'Alice', email: '[email protected]' },
  { id: 2, name: 'Bob', email: '[email protected]' }
])
</script>

Style example:

<style scoped>
h1 { font-weight: 700 }
</style>

Metadata (YAML frontmatter)

MDV supports YAML frontmatter, compiled into a .meta.json file alongside the component.

Example frontmatter:

---
title: Hello World
description: This is my first MDV page
---

# {{ $meta.title }}

Emitted files:

  • HelloWorld.vue (compiled component)
  • HelloWorld.meta.json (metadata)

Accessing metadata:

  • From script: useMeta() always returns a Promise and should be awaited.
import { useMeta } from "mdv";
const meta = await useMeta();
const otherMeta = await useMeta("/path/to/other");
  • From templates: $meta is available ({{ $meta.title }}).

Example: Full Vue App in Markdown

<v-app>
  # My Markdown-Vue App

This is an MDV page with components and markdown.

  <section>
    <h2>Users</h2>
    <ul>
      <li v-for="(u, i) in users" :key="u.id || i">
        <UserBadge :user="u" />
      </li>
    </ul>
  </section>
</v-app>

<script setup>
import UserBadge from './UserBadge.vue'
import { ref } from 'vue'

const users = ref([
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' }
])
</script>

Use cases

  • Static websites
  • Repo-based CMS
  • Documentation & Blogs with interactive components

Notes & best practices

  • Prefer Vue-style attributes (v-... and :) and include :key on v-for lists.

  • Use the inline shorthand forms only:

    • [text]{ ::ComponentName ...props ...directives }
    • :[expression]{ ::ComponentName }
  • Use full HTML/Vue tags for multiple named slots or complex layouts.

  • Keep scripts/styles in-file for small pages; split out for complexity.