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.
# npm
npm install -D vitepress vitepress-tuck
# pnpm
pnpm add -D vitepress vitepress-tuck
# yarn
yarn add -D vitepress vitepress-tuck
# bun
bun add -D vitepress 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 | Description | |
|---|---|---|
| vitepress-plugin-abbr | Abbreviation display, supports custom tags and content | |
| vitepress-plugin-steps | Step container for creating step guidance content | |
| vitepress-plugin-file-tree | File directory tree display, supports expand/collapse | |
| vitepress-plugin-code-tree | Code tree display, supports expand/collapse | |
| vitepress-plugin-plot | Hidden text mask, click or hover to reveal hidden text (!!text!! syntax) |
|
| vitepress-plugin-npm-to | npm commands are automatically converted to pnpm / yarn / bun / deno commands |
|
| vitepress-plugin-repo-card | GitHub / Gitee repository card display | |
| vitepress-plugin-mermaid-tuck | Mermaid diagram rendering | |
| vitepress-plugin-plantuml | PlantUML diagram rendering | |
| vitepress-plugin-qrcode | QR code generation, supports two modes: image and card | |
| vitepress-plugin-video | Multi-platform video embedding(Bilibili、YouTube、AcFun、ArtPlayer) | |
| vitepress-plugin-obsidian | Obsidian-style Markdown syntax (Wiki links, Callout, embeds, comments) | |
| vitepress-plugin-pdf | Embed PDF file, supporting configuration of page number, zoom, toolbar, etc | |
| vitepress-plugin-caniuse | Embed caniuse.com browser compatibility data | |
| vitepress-plugin-code-collapse | Code block line collapse, supporting global/single block configuration | |
| vitepress-plugin-codepen | Embed CodePen examples, support custom tags and themes | |
| vitepress-plugin-jsfiddle | Embed JSFiddle examples with support for custom tabs. | |
| vitepress-plugin-watermark | Watermark display, supports custom content and styles |
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