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

@knowvah/vitepress-plugin-dot

v2.0.0

Published

Render Graphviz DOT fenced code blocks to inline SVG in VitePress — at build time, no client JS, powered by the pure-TypeScript @knowvah/dot-engine.

Readme

@knowvah/vitepress-plugin-dot

Render Graphviz DOT fenced code blocks to inline SVG in VitePressat build time, with no client-side JavaScript — powered by the pure-TypeScript @knowvah/dot-engine.

Unlike client-rendered diagram plugins (e.g. mermaid, which ships a WASM/JS runtime and renders in the browser on mount), @knowvah/dot-engine is synchronous and runs in Node, so this plugin renders each diagram during vitepress build and embeds static <svg> directly in the HTML:

  • No client JS for diagrams, no hydration, no flash of unrendered code.
  • Works on any static host, in email, in offline docs.
  • Fails gracefully — a bad graph becomes a readable error panel, not a broken build.
```dot
digraph {
  rankdir=LR;
  parse -> layout -> render;
}
```

Install

npm i -D @knowvah/vitepress-plugin-dot @knowvah/dot-engine

@knowvah/dot-engine is a peer dependency — you install the engine version you want.

Usage

Wrap your VitePress config and import the stylesheet in your theme:

// docs/.vitepress/config.ts
import { defineConfig } from 'vitepress';
import { withDot } from '@knowvah/vitepress-plugin-dot';

export default withDot(
  defineConfig({
    title: 'My Docs',
  }),
  {
    // options (all optional)
    defaultEngine: 'dot',
    useCurrentColor: true, // inherit theme text color (nice in dark mode)
  },
);
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme';
import '@knowvah/vitepress-plugin-dot/style.css';

export default DefaultTheme;

That's it. Now ```dot blocks render.

Per-block engine

Per-block options go in the fence info, space-separated — not in {...} (VitePress reserves curly braces in fence info for line highlighting and strips them before the plugin sees them):

```dot engine=neato
graph { a -- b -- c -- a }
```

Client-side render mode

By default diagrams render at build time (static SVG). Set mode: 'client' globally, or add client to a single block, to render in the browser on mount instead — useful for untrusted or interactive graphs. Add build to a block to force build-time rendering when the global default is client.

```dot client
digraph { a -> b }
```

Client mode requires registering the DotDiagram component in your theme:

// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme';
import { DotDiagram } from '@knowvah/vitepress-plugin-dot/client';

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    app.component('DotDiagram', DotDiagram);
  },
};

Trade-offs: build mode ships zero JS and renders instantly; client mode ships the @knowvah/dot-engine to the browser (lazy-loaded on first diagram) and shows a brief mount delay, but keeps a pathological graph off your build and re-renders nothing on navigation. Both honor useCurrentColor for dark mode.

Opt a block out (keep it as source)

Add no-render and the plugin hands the block back to VitePress's fence renderer untouched:

```dot no-render
digraph { a -> b }
```

Highlighting DOT source

The plugin renders diagrams; it does not provide syntax highlighting. Any DOT block it doesn't render — no-render blocks, or all dot blocks when renderLanguage is something else — is delegated to VitePress's Shiki highlighter, and Shiki bundles no DOT/Graphviz grammar, so those blocks show as plain (uncolored) text.

To colorize DOT source, register a TextMate grammar for it via markdown.languages:

// docs/.vitepress/config.ts
import dotGrammar from './dot.tmLanguage'; // a TextMate grammar (scopeName source.dot)

export default withDot(
  defineConfig({
    markdown: { languages: [dotGrammar] },
  }),
);

A ready-made DOT grammar is in the @knowvah/dot-engine docs (docs-site/.vitepress/dot.tmLanguage.ts), or use any community source.dot TextMate grammar.

Compose with other markdown plugins

withDot preserves any existing markdown.config hook, so it composes with plugins like vitepress-plugin-mermaid:

export default withDot(withMermaid(defineConfig({ /* ... */ })));

You can also skip the wrapper and register the markdown-it plugin directly:

import { dotMarkdown } from '@knowvah/vitepress-plugin-dot/markdown-it';

export default defineConfig({
  markdown: {
    config: (md) => dotMarkdown(md, { defaultEngine: 'dot' }),
  },
});

Options

| Option | Type | Default | Description | | ----------------- | ---------------------- | ------------ | ----------------------------------------------------------------------------------------------- | | renderLanguage | string | "dot" | The fence info-string that triggers rendering. Set to "graphviz" to leave ```dot as source. | | mode | 'build' \| 'client' | "build" | Render at build time (inline SVG) or in the browser. Per-block: add client or build to the fence. | | defaultEngine | EngineName | "dot" | Layout engine when a block doesn't specify one. Per-block: ```dot engine=neato. | | wrapperClass | string | "dot-diagram" | CSS class on the wrapper <div> (and <class>-error on the error panel). | | timeout | number (ms) | — | Build mode only: render in a child process with this timeout (see Security). | | onError | 'panel' \| 'throw' | "panel" | Build mode only: show an error box, or fail the build on the first bad diagram. | | useCurrentColor | boolean | false | Remap Graphviz's default black strokes/text to currentColor for theme-aware (dark-mode) diagrams. |

Engines: dot, neato, fdp, sfdp, circo, twopi, osage, patchwork.

Security

The rendered SVG is derived from the DOT source. For untrusted, user-supplied DOT, the output is attacker-controlled markup — apply a Content-Security-Policy and/or sanitize before serving, and prefer the timeout option so a pathological graph (Graphviz layout can be pathologically slow, and a malicious graph could try to hang the build) is aborted to an error panel instead of stalling vitepress build. For trusted author content (the common docs case), the default in-process render is fast and safe.

Note for the @knowvah/dot-engine docs site: it intentionally keeps a documented infinite-loop DOT example as highlighted source. There, set renderLanguage: 'graphviz' (or mark such blocks ```dot no-render) so they are not rendered.

How it works

A markdown-it fence rule matches the configured language, calls tryRenderSvg(code, engine) from @knowvah/dot-engine, strips the standalone-document prolog/DOCTYPE, and emits the inline <svg> in a wrapper <div>. Non-matching fences (and no-render blocks) fall through to VitePress's normal Shiki highlighting, untouched.

Stability

As of 1.0, this package follows semantic versioning: the documented public API is stable, and breaking changes will bump the major version.

License

MIT © Knowvah