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

remark-directive-sugar

v2.0.0

Published

Remark plugin built on remark-directive, providing predefined directives for image captions, video embedding, styled GitHub links, badges, and more.

Readme

remark-directive-sugar

version codecov npm downloads jsDocs.io

A remark plugin provides predefined directives for customizable badges, links, video embeds, enhanced image formatting, and more.

What is this?

This plugin is built on top of remark-directive, supporting regular usage and providing the following predefined directives:

  • :badge[-*]: Generates customizable badges.
  • :link: Creates links to GitHub, npm, or custom URLs.
  • ::video[-*]: Embeds videos from platforms like YouTube, Bilibili, Vimeo, or custom sources.
  • :::image-*: Wraps an image inside valid HTML tags, such as a <figure> element to allow adding a descriptive <figcaption>, or a hyperlink to make it clickable, and more.

When should I use this?

If you're using remark-directive, this plugin provides ready-to-use directives, saving you from writing custom code. If you're building a blog with frameworks like Astro or Next.js, it helps enhance your Markdown / MDX content without repetitive HTML.

[!NOTE]
This plugin requires remark-directive, so make sure to install it as well. Check out the Remark Directive Syntax for a quick and easy overview!

Installation

This package is ESM only. In Node.js (version 16+), install with your package manager:

npm install remark-directive-sugar
yarn add remark-directive-sugar
pnpm add remark-directive-sugar

In Deno with esm.sh:

import remarkDirectiveSugar from 'https://esm.sh/remark-directive-sugar'

In browsers with esm.sh:

<script type="module">
  import remarkDirectiveSugar from 'https://esm.sh/remark-directive-sugar?bundle'
</script>

Usage

Import and configure the plugin based on your target environment.

For vanilla JS:

// example.js
import { unified } from 'unified'
import remarkParse from 'remark-parse'
import remarkDirective from 'remark-directive'
import remarkDirectiveSugar from 'remark-directive-sugar'
import remarkRehype from 'remark-rehype'
import rehypeStringify from 'rehype-stringify'
import { readSync } from 'to-vfile'

const file = unified()
  .use(remarkParse)
  .use(remarkDirective)
  .use(remarkDirectiveSugar)
  .use(remarkRehype)
  .use(rehypeStringify)
  .processSync(readSync('example.md'))

console.log(String(file))

For Astro projects:

// astro.config.ts
import { defineConfig } from 'astro/config'
import remarkDirective from 'remark-directive'
import remarkDirectiveSugar from 'remark-directive-sugar'

// https://docs.astro.build/en/reference/configuration-reference/
export default defineConfig({
  markdown: {
    remarkPlugins: [remarkDirective, remarkDirectiveSugar],
  },
})

For Next.js projects:

// next.config.ts
import createMDX from '@next/mdx'
import remarkDirective from 'remark-directive'
import remarkDirectiveSugar from 'remark-directive-sugar'
import type { NextConfig } from 'next'

// https://nextjs.org/docs/app/api-reference/config/next-config-js
const nextConfig: NextConfig = {
  pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
}

const withMDX = createMDX({
  options: {
    remarkPlugins: [remarkDirective, remarkDirectiveSugar],
    // With Turbopack, specify plugin names as strings
    // remarkPlugins: [['remark-directive'],['remark-directive-sugar']],
  },
})

export default withMDX(nextConfig)

All predefined directives generate only the HTML structure, allowing you to style them with class names or attributes.

:badge[-*]

Use :badge[-*] directive to display small pieces of information, such as status or category. Say example.md contains:

<!-- Direct usage with text in `[]` -->

Example 1: :badge[New]
Example 2: :badge[Success]{style="color: black; background-color: #aaf233"}

<!-- Using presets: `presets: {a: { text: 'ARTICLE' }, v: { text: 'VIDEO', props: { className: ['custom'] } }}` -->

Example 3: :badge-a
Example 4: :badge-v

Run node example.js (pnpm dev) to get:

<p>
  Example 1: <span class="rds-badge">New</span>
  Example 2: <span style="color: black; background-color: #aaf233" class="rds-badge">Success</span>
</p>
<p>
  Example 3: <span data-badge="a" class="rds-badge">ARTICLE</span>
  Example 4: <span data-badge="v" class="rds-badge custom">VIDEO</span>
</p>

:link

Use :link directive to create links with avatars or favicons for GitHub, npm, or custom URLs. Say example.md contains:

<!-- Link to a GitHub user or organization (prepend `id` or `#` with `@`) -->
<!-- Use `tab` to navigate sections: -->
<!-- for users: 'repositories', 'projects', 'packages', 'stars', 'sponsoring', 'sponsors' -->
<!-- for orgs: 'org-repositories', 'org-projects', 'org-packages', 'org-sponsoring', 'org-people' -->

Example 1: :link{#@lin-stephanie}
Example 2: :link{#@lin-stephanie tab=repositories}
Example 3: :link[Vite]{id=@vitejs}
Example 4: :link[Vite]{id=@vitejs tab=org-people}

<!-- Link to a GitHub repository -->

Example 5: :link{#lin-stephanie/remark-directive-sugar}
Example 6: :link[Astro]{id=withastro/astro}

<!-- Link to an npm package -->
<!-- Use `tab` to navigate sections: 'readme', 'code', 'dependencies', 'dependents', 'versions' -->

Example 7: :link{#remark-directive-sugar}
Example 8: :link{id=remark-directive-sugar tab=dependencies}

<!-- Link to a custom URL (must use `id`, not `#`) -->

Example 9: :link{id=https://developer.mozilla.org/en-US/docs/Web/JavaScript}
Example 10: :link[Google]{id=https://www.google.com/}

<!-- Use `url` to override the default link -->
<!-- Use `img` to set a custom display image -->

Example 11: :link[Vite]{id=@vitejs url=https://vite.dev/}
Example 12: :link[Vite]{id=@vitejs img=https://vitejs.dev/logo.svg}

Run node example.js (pnpm dev) to get:

<p>
  Example 1:
  <a href="https://github.com/lin-stephanie" data-link="github-acct" class="rds-link">
    <img src="https://github.com/lin-stephanie.png" alt="" />
    lin-stephanie
  </a>
  Example 2:
  <a href="https://github.com/lin-stephanie?tab=repositories" data-link="github-acct" class="rds-link">
    <img src="https://github.com/lin-stephanie.png" alt="" />
    lin-stephanie
  </a>
  Example 3:
  <a href="https://github.com/vitejs" data-link="github-acct" class="rds-link">
    <img src="https://github.com/vitejs.png" alt="" />
    Vite
  </a>
  Example 4:
  <a href="https://github.com/orgs/vitejs/people" data-link="github-acct" class="rds-link">
    <img src="https://github.com/vitejs.png" alt="" />
    Vite
  </a>
</p>

<p>
  Example 5:
  <a href="https://github.com/lin-stephanie/remark-directive-sugar" data-link="github-repo" class="rds-link">
    <img src="https://github.com/lin-stephanie.png" alt=""/>
    lin-stephanie/remark-directive-sugar
  </a>
  Example 6:
  <a href="https://github.com/withastro/astro" data-link="github-repo" class="rds-link">
    <img src="https://github.com/withastro.png" alt="" />
    Astro
  </a>
</p>

<p>
  Example 7:
  <a href="https://www.npmjs.com/package/remark-directive-sugar" data-link="npm-pkg" class="rds-link">
    <img src="https://api.faviconkit.com/www.npmjs.com" alt="">
    remark-directive-sugar
  </a>
  Example 8:
  <a href="https://www.npmjs.com/package/remark-directive-sugar?activeTab=dependencies" data-link="npm-pkg" class="rds-link">
    <img src="https://api.faviconkit.com/www.npmjs.com" alt="">
    remark-directive-sugar
  </a>
</p>

<p>
  Example 9:
  <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" data-link="custom-url" class="rds-link">
    <img src="https://api.faviconkit.com/developer.mozilla.org" alt="">
    developer.mozilla.org/en-US/docs/Web...
  </a>
  Example 10:
  <a href="https://www.google.com/" data-link="custom-url" class="rds-link">
    <img src="https://api.faviconkit.com/www.google.com" alt="">
    Google
  </a>
</p>

<p>
  Example 11:
  <a href="https://vite.dev/" data-link="github-acct" class="rds-link">
    <img src="https://github.com/vitejs.png" alt="">
    Vite
  </a>
  Example 12:
  <a href="https://github.com/vitejs" data-link="github-acct" class="rds-link">
    <img src="https://vitejs.dev/logo.svg" alt="">
    Vite
  </a>
</p>

::video[-*]

Use ::video[-*] for consistent video embedding across different platforms. Say example.md contains:

<!-- Embed a YouTube video -->

::video-youtube{#gxBkghlglTg}

<!-- Embed a Bilibili video -->

::video-bilibili{id=BV1MC4y1c7Kv}

<!-- Embed a Vimeo video with a custom `title` attr -->

::video-vimeo[custom title]{id=912831806}

<!-- Embed a custom video URL (must use `id`, not `#`) -->

::video{id=https://www.youtube-nocookie.com/embed/gxBkghlglTg}

Run node example.js (pnpm dev) to get:

<iframe
  src="https://www.youtube-nocookie.com/embed/gxBkghlglTg"
  title="Video Player"
  data-video="youtube"
  class="rds-video"
></iframe>

<iframe
  src="https://player.bilibili.com/player.html?bvid=BV1MC4y1c7Kv"
  title="Video Player"
  data-video="bilibili"
  class="rds-video"
></iframe>

<iframe
  src="https://player.vimeo.com/video/912831806"
  title="custom title"
  data-video="vimeo"
  class="rds-video"
></iframe>

<iframe
  src="https://www.youtube-nocookie.com/embed/gxBkghlglTg"
  title="Video Player"
  data-video="url"
  class="rds-video"
></iframe>

:::image-*

Use :::image-* to wrap images in a container for captions, clickable links, and more (* must be a valid HTML tag). Say example.md contains:

<!-- `:::image-figure[caption]{<figcaption> attrs}` -->
<!-- `[]` hold the figcaption,if not set, the alt text from `![]()` will be used as the default -->

:::image-figure[Figcaption text]
![Alt text](https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg)
:::

:::image-figure{style="text-align:center; color:orange"}
![Text for both alt and figcaption](https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg)
:::

<!-- `:::image-a{<a> attrs}` -->

:::image-a{href="https://github.com/lin-stephanie/remark-directive-sugar"}
![](https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg)
:::

<!-- `:::image-*{<*> attrs}` -->

:::image-div
![](https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg)
:::

<!-- Setting `stripParagraph: false` keeps `<p>` to prevent parsing issues with other remark plugins like `remark-imgattr` -->

:::image-figure[Figcaption text]
![Alt text](https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg)
:::

:::image-a{href="https://github.com/lin-stephanie/remark-directive-sugar"}
![](https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg)
:::

Run node example.js (pnpm dev) to get:

<figure>
  <img src="https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg" alt="Alt text">
  <figcaption>Figcaption text</figcaption>
</figure>

<figure>
  <img src="https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg" alt="Text for both alt and figcaption">
  <figcaption style="text-align:center; color:orange">Text for both alt and figcaption</figcaption>
</figure>

<a href="https://github.com/lin-stephanie/remark-directive-sugar">
  <img src="https://images.pexels.com/photos/237272/pexels-photo-237273.jpeg" alt="">
</a>

<div>
  <img src="https://images.pexels.com/photos/237272/pexels-photo-237273.jpeg" alt="">
</div>

<figure>
  <p>
    <img src="https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg" alt="Alt text">
  </p>
  <figcaption>Figcaption text</figcaption>
</figure>

<a href="https://github.com/lin-stephanie/remark-directive-sugar">
  <p>
    <img src="https://images.pexels.com/photos/237273/pexels-photo-237273.jpeg" alt="">
  </p>
</a>

API

This package exports no identifiers. The default export is remarkDirectiveSugar.

unified().use(remarkDirectiveSugar[, options])

Used to provid predefined directives.

Parameters
  • options (Options, optional) — configuration
Returns

Transform (Transformer).

Options

Configuration (TypeScript type). All options are optional.

Fields

Types

This package is fully typed with TypeScript. It exports the additional types Options, BadgeDirectiveConfig, LinkDirectiveConfig, VideoDirectiveConfig, ImageDirectiveConfig, PropertiesFromContainerDirective, PropertiesFromLeafDirective and PropertiesFromTextDirective. See jsDocs.io for type details.

Contribution

If you see any errors or room for improvement on this plugin, feel free to open an issues or pull request . Thank you in advance for contributing!

License

MIT © 2024-PRESENT Stephanie Lin