English | 简体中文
A low-barrier, extensible plugin development library and plugin ecosystem for VitePress
vitepress-tuck is a plugin development library and plugin collection designed for VitePress.
It provides a clean, unified plugin interface and configuration merging mechanism,
significantly lowering the barrier to developing VitePress plugins while offering a more user-friendly integration experience.
- Low Barrier — Plugin developers only need to focus on core logic; no need to handle complex VitePress configuration merging and lifecycle orchestration.
- Easy Integration — Plugin users simply pass a
pluginsarray todefineConfig, and plugins automatically handle configuration injection. - Progressive Compatibility — All plugins work with both
vitepress-tuckand native VitePress integration.
pnpm add vitepress-tuckReplace VitePress's defineConfig with vitepress-tuck's defineConfig:
// .vitepress/config.ts
import { defineConfig } from 'vitepress-tuck'
export default defineConfig({
plugins: [
// Add plugins here
],
// Other VitePress config options ...
})defineConfig is fully compatible with all parameters of VitePress's native defineConfig, with the additional plugins option.
In .vitepress/theme/index.ts, import virtual:enhance-app to automatically inject plugin client code:
// .vitepress/theme/index.ts
import type { Theme } from 'vitepress'
import enhanceApp from 'virtual:enhance-app'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
enhanceApp(ctx) {
enhanceApp(ctx)
},
} satisfies Themevirtual:enhance-app is a virtual module provided by vitepress-tuck that automatically collects and merges all plugins' client configurations.
For TypeScript support, add type references in
tsconfig.json:{ "compilerOptions": { "types": ["vitepress-tuck/client-types"] } }
vitepress-tuck integrates unplugin-vue-components as
a built-in plugin, enabling automatic on-demand component importing for .vue and .md files — no manual import
or registration required. Plugins can declare their Vue components via the componentResolver field,
and users can use them directly in Markdown or Vue files.
You can customize the behavior via the components option:
// .vitepress/config.ts
import { defineConfig } from 'vitepress-tuck'
export default defineConfig({
components: {
// Any unplugin-vue-components options, e.g.:
dirs: ['src/components'],
},
plugins: [],
})All plugins are built on vitepress-tuck while remaining compatible with native VitePress.
| Plugin | Package | Description |
|---|---|---|
| Steps | vitepress-plugin-steps |
Step-by-step container for creating guided content |
| File Tree | vitepress-plugin-file-tree |
Render file directory trees with expand/collapse |
| Code Tree | vitepress-plugin-code-tree |
Code tree with file tree sidebar |
| Plot | vitepress-plugin-plot |
Hidden text with click/hover reveal (!!text!! syntax) |
| Npm To | vitepress-plugin-npm-to |
Convert npm commands to pnpm / yarn / bun / deno equivalents |
| Repo Card | vitepress-plugin-repo-card |
GitHub / Gitee repository card display |
| Mermaid | vitepress-plugin-mermaid-tuck |
Mermaid diagram rendering with i18n support |
| PlantUML | vitepress-plugin-plantuml |
PlantUML diagram rendering with i18n support |
| QRCode | vitepress-plugin-qrcode |
Generate QR codes (image/card modes) |
| Video | vitepress-plugin-video |
Multi-platform video embedding (Bilibili, YouTube, AcFun, ArtPlayer) |
| Obsidian | vitepress-plugin-obsidian |
Obsidian-style Markdown (Wiki links, Callouts, embeds, comments) |
vitepress-plugin-pdf |
Embed PDF files with page/zoom/toolbar options | |
| Can I Use | vitepress-plugin-caniuse |
Embed browser compatibility data from caniuse.com |
| Code Collapse | vitepress-plugin-code-collapse |
Fold long code blocks (global / per-block configuration) |
| CodePen | vitepress-plugin-codepen |
Embed CodePen demos with custom tabs and themes |
| JSFiddle | vitepress-plugin-jsfiddle |
Embed JSFiddle demos with custom tabs |
Creating a VitePress plugin with vitepress-tuck is straightforward:
// src/node/index.ts
import { definePlugin } from 'vitepress-tuck'
export default definePlugin((options?: MyPluginOptions) => ({
name: 'vitepress-plugin-example',
// Client configuration: auto-injected into virtual:enhance-app
client: {
imports: [
'import "vitepress-plugin-example/style.css"',
],
enhance: 'enhanceAppWithExample',
},
// Component resolver: declare components for auto on-demand import
componentResolver: ['MyComponent', 'OtherComponent'],
// Markdown configuration: register markdown-it plugins
markdown: {
config: (md) => {
md.use(yourMarkdownItPlugin, options?.markdownOptions)
},
},
// Vite configuration
vite: {
plugins: [yourVitePlugin(options?.viteOptions)],
ssr: {
noExternal: ['vitepress-plugin-example'],
},
},
// VitePress lifecycle hooks
buildEnd: (siteConfig) => { /* ... */ },
transformHead: (context) => { /* ... */ },
transformHtml: (code, id, context) => { /* ... */ },
transformPageData: (pageData, context) => { /* ... */ },
postRender: (context) => { /* ... */ },
}))- Use vitepress-plugin-toolkit which provides
createEmbedRuleBlock,createContainerPlugin,createContainerSyntaxPluginand other utilities for quickly building markdown-it plugins. - See the full API reference for
VitepressPlugintype definitions. - Refer to existing plugins in this repository as development examples.
You can easily wrap any existing plugin logic into a vitepress-tuck compatible form using definePlugin:
import { definePlugin } from 'vitepress-tuck'
import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons'
export default definePlugin(() => ({
name: 'vitepress-plugin-group-icons',
client: {
imports: ['import \'virtual:group-icons.css\''],
},
markdown: {
config: (md) => {
md.use(groupIconMdPlugin)
},
},
vite: {
plugins: [groupIconVitePlugin()],
ssr: {
noExternal: ['vitepress-plugin-group-icons'],
},
},
}))All plugins in this project can also be used independently without vitepress-tuck, directly in native VitePress:
// .vitepress/config.ts
import { defineConfig } from 'vitepress'
import { qrcodePlugin } from 'vitepress-plugin-qrcode'
export default defineConfig({
markdown: {
config(md) {
md.use(qrcodePlugin)
},
},
vite: {
plugins: [
// vite config...
],
},
})
// .vitepress/theme/index.ts
import type { Theme } from 'vitepress'
import { enhanceAppWithQrcode } from 'vitepress-plugin-qrcode/client'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
enhanceApp(ctx) {
enhanceAppWithQrcode(ctx)
},
} satisfies Theme