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

vitepress-dgmo

v0.2.9

Published

VitePress integration to render DGMO diagrams from fenced code blocks at build time. A markdown-it fence override backed by an async pre-render cache — `withDgmo()` wires both into your .vitepress/config.ts in one call.

Readme

vitepress-dgmo

Render Diagrammo (DGMO) diagrams from fenced dgmo code blocks in your VitePress docs — at build time, as inline SVG. No client-side rendering, no runtime diagram library shipped to readers.

🔭 Live showcase: every chart type rendered through vitepress-dgmo — every block is in showcase mode, so hovering a diagram reveals its copy / open-in-editor footer.

```dgmo
flowchart
[Start] -> [End]
```

Why this package is different

The other Diagrammo docs integrations (astro-dgmo, docusaurus-plugin-dgmo, fumadocs-dgmo) are thin wrappers around the shared remark-dgmo plugin. VitePress does not use remark — it renders markdown with markdown-it — so that plugin can't be reused. vitepress-dgmo is a markdown-it integration built from scratch, sharing only dgmo's render() and the showcase CSS.

Install

pnpm add -D vitepress-dgmo @diagrammo/dgmo
# or: npm i -D vitepress-dgmo @diagrammo/dgmo

@diagrammo/dgmo and vitepress are peer dependencies.

Setup

1. Wrap your config

// .vitepress/config.ts
import { defineConfig } from 'vitepress';
import { withDgmo } from 'vitepress-dgmo';

export default defineConfig(
  withDgmo(
    {
      title: 'My Docs',
      // ...the rest of your VitePress config
    },
    { palette: 'slate' } // dgmo options (optional)
  )
);

withDgmo registers both halves of the integration (see How it works) while preserving any markdown.config and vite.plugins you already have.

2. (Optional) client enhancement + styles

Diagrams are fully rendered at build time, so this step is optional. It adds light/dark toggling styles, viewBox tightening, and showcase copy / open-in-editor buttons.

// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme';
import { setupDgmo } from 'vitepress-dgmo/client';
import 'vitepress-dgmo/client.css';

export default {
  extends: DefaultTheme,
  enhanceApp({ router }) {
    setupDgmo(router); // re-tightens SVGs + wires buttons on every route change
  },
};

The stylesheet keys light/dark visibility on VitePress's <html class="dark"> convention automatically.

Usage in markdown

Write a fenced block with the dgmo language:

```dgmo
sequence
Alice -> Bob
```

Per-block options (fence meta)

Everything after dgmo on the fence line configures that block:

```dgmo showcase palette=catppuccin theme=light title="Login flow"
flowchart
[User] -> [Login]
```

| Meta token | Effect | | --------------------------------------------------------------------------- | --------------------------------------------------------- | | showcase / diagram | Output mode for this block (source + chrome vs SVG only). | | palette=<name> | Palette for this block. | | theme=light\|dark\|transparent | Theme (only when colorMode isn't auto). | | colorMode=auto\|light\|dark | Color-mode strategy for this block. | | title="…" | Caption. | | noSource / source, noCopy / copy, noOpenInEditor / openInEditor | Toggle showcase chrome. |

Options

Passed as the second argument to withDgmo. A subset of remark-dgmo's DgmoOptions.

| Option | Type | Default | Description | | ---------------------------------------------- | ------------------------------------ | ------------------------------ | ------------------------------------------------------------------------ | | palette | string | 'slate' | Default palette name. | | theme | 'light' \| 'dark' \| 'transparent' | 'dark' | Default theme (only consulted when colorMode is not auto). | | colorMode | 'auto' \| 'light' \| 'dark' | 'auto' | auto dual-renders light + dark SVGs and toggles them via client.css. | | mode | 'diagram' \| 'showcase' | 'diagram' | showcase adds syntax-highlighted source + copy + open-in-editor. | | editorBaseUrl | string | https://online.diagrammo.app | Base URL for the "Open in editor" link. | | showSource / showCopy / showOpenInEditor | boolean | mode-dependent | Fine-grained showcase chrome toggles. | | className | string | 'dgmo' | Outer wrapper class. |

How it works

markdown-it's renderer.rules.fence is strictly synchronous, but dgmo's render() is async. vitepress-dgmo bridges that gap with a two-phase design, both halves sharing one cache:

  1. Async warm-cache pre-pass — a Vite plugin (enforce: 'pre') whose transform hook runs on every .md module before VitePress compiles it. It scans the raw markdown for dgmo fences, awaits render() for each (dual light + dark under colorMode: auto), sanitizes the SVG, and stores the resulting HTML in a cache keyed by a stable hash of (source, meta, options). Render failures are cached as an inline error card, never thrown.

  2. Sync markdown-it fence override — registered via VitePress's markdown.config(md). For a dgmo fence it recomputes the same hash from the token and returns the pre-rendered HTML from the cache. Any other language delegates to the original fence renderer untouched.

Because both phases run for the same module in sequence (pre transform, then VitePress's markdown transform), the cache is always warm by the time the fence rule reads it. A cache miss (which shouldn't happen when withDgmo wires both halves) degrades to a visible placeholder plus a console warning rather than a crash.

The v-pre guard

VitePress compiles the HTML that markdown-it emits as a Vue template. Raw SVG routinely contains {{, <, and > in text labels and path data, which Vue would mis-parse as interpolation or markup. So every rendered block is wrapped in <div class="dgmo-vp" v-pre>…</div> — the v-pre directive tells Vue to emit the element and all its children verbatim, skipping template compilation.

Advanced: wire the two phases yourself

If you'd rather not let withDgmo merge your config, build a matched pair from one shared cache and place them yourself:

import { createDgmoParts } from 'vitepress-dgmo';

const { dgmoMarkdown, dgmoVitePlugin } = createDgmoParts({ palette: 'slate' });

export default defineConfig({
  markdown: { config: (md) => dgmoMarkdown(md) },
  vite: { plugins: [dgmoVitePlugin] },
});

Both must come from the same createDgmoParts() call — that shared cache is the whole mechanism.

License

MIT © Demian Neidetcher