Writing a plugin for Vite, webpack, Rollup, Rspack, AND esbuild means 5 different APIs. Unplugin lets you write it once — it works everywhere.
What Is Unplugin?
Unplugin is a universal plugin system from the UnJS ecosystem. Write one plugin that runs on Vite, Rollup, webpack, Rspack, esbuild, and Rolldown.
Quick Start
npm install unplugin
import { createUnplugin } from 'unplugin';
const myPlugin = createUnplugin((options) => ({
name: 'my-plugin',
transformInclude(id) {
return id.endsWith('.ts');
},
transform(code, id) {
return code.replace(/__VERSION__/g, '"1.0.0"');
},
buildStart() {
console.log('Build started!');
},
}));
// Export for each bundler
export const vite = myPlugin.vite;
export const webpack = myPlugin.webpack;
export const rollup = myPlugin.rollup;
export const rspack = myPlugin.rspack;
export const esbuild = myPlugin.esbuild;
Popular Unplugins
unplugin-auto-import
Auto-import APIs — no more manual imports:
// Before
import { ref, computed, watch } from 'vue';
import { useRouter } from 'vue-router';
// After (auto-imported)
const count = ref(0);
const double = computed(() => count.value * 2);
const router = useRouter();
unplugin-vue-components
Auto-import Vue components — no registration needed:
<template>
<!-- Components auto-imported, no import statement needed -->
<ElButton type="primary">Click me</ElButton>
<van-field v-model="value" label="Name" />
</template>
unplugin-icons
Use 100K+ icons from Iconify as components:
import IconAccessibility from '~icons/mdi/accessibility';
import IconAccountBox from '~icons/mdi/account-box';
<IconAccessibility />
<IconAccountBox style={{ fontSize: '2rem', color: 'red' }} />
Creating Your Own Unplugin
import { createUnplugin } from 'unplugin';
export const unpluginMarkdown = createUnplugin((options) => ({
name: 'unplugin-markdown',
// Only process .md files
transformInclude(id) {
return id.endsWith('.md');
},
// Transform markdown to HTML module
transform(code, id) {
const html = markdownToHtml(code);
return `export default ${JSON.stringify(html)}`;
},
// Virtual modules
resolveId(id) {
if (id === 'virtual:my-module') return id;
},
load(id) {
if (id === 'virtual:my-module') {
return 'export const data = "hello from virtual module"';
}
},
}));
Available Hooks
| Hook | Description |
|---|---|
buildStart |
Called when build starts |
resolveId |
Resolve module IDs |
load |
Load module content |
transform |
Transform module code |
buildEnd |
Called when build ends |
writeBundle |
After files written |
watchChange |
File changed in watch mode |
Why Unplugin
- Write once — works across 6 bundlers
- Same API — consistent hook system
- Ecosystem — 50+ community unplugins
- UnJS quality — maintained by the Nuxt team
Get Started
- Documentation
- GitHub — 4K+ stars
- Ecosystem
Building developer tools? My Apify scrapers are built with the same quality standards. Custom solutions: spinov001@gmail.com
Top comments (0)