DEV Community

Alex Spinov
Alex Spinov

Posted on

Unplugin Has Free Universal Build Plugins — Here's How to Use Them

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
Enter fullscreen mode Exit fullscreen mode
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;
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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' }} />
Enter fullscreen mode Exit fullscreen mode

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"';
    }
  },
}));
Enter fullscreen mode Exit fullscreen mode

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


Building developer tools? My Apify scrapers are built with the same quality standards. Custom solutions: spinov001@gmail.com

Top comments (0)