Vue.js Plugins

A plugin is a reusable package that adds features to a whole Vue application. Routers, state stores, and translation tools all arrive as plugins. You can also write your own to share a toast message system, a custom directive, or a set of global helper functions across every component without importing them one by one.

Think of a power strip. One plug in the wall feeds many devices. A plugin connects once at the application level, and every component gets access to the feature.

Install a Plugin with app.use

The app.use() method installs a plugin before the app mounts. Official plugins follow this pattern.

import { createApp } from "vue";
import { createPinia } from "pinia";
import router from "./router";
import App from "./App.vue";

const app = createApp(App);
app.use(createPinia());
app.use(router);
app.mount("#app");

Diagram: Plugin Installation

createApp(App)
   |-- app.use(pinia)   --> adds stores
   |-- app.use(router)  --> adds routing
   |-- app.mount()      --> app starts with all features

Write a Plugin

A plugin is either an object with an install method or a plain function. Vue calls it with the app object and any options you pass.

// plugins/greeter.js
export default {
  install(app, options) {
    app.config.globalProperties.$greet = (name) => {
      return options.prefix + ", " + name + "!";
    };
  }
};
// main.js
import greeter from "./plugins/greeter.js";

app.use(greeter, { prefix: "Welcome" });

Templates call the new helper directly.

<p>{{ $greet("Maya") }}</p>   <!-- Welcome, Maya! -->

Diagram: Plugin Flow

app.use(greeter, { prefix: "Welcome" })
        |
        v
install(app, options) runs once
        |
        v
every component can call $greet("Maya")

What a Plugin Can Add

  • Global properties and methods through app.config.globalProperties
  • Global components through app.component()
  • Custom directives through app.directive()
  • Shared values for descendants through app.provide()

A Plugin That Registers Components and Directives

A UI kit plugin often bundles several parts together.

// plugins/uikit.js
import BaseButton from "../components/BaseButton.vue";
import BaseCard from "../components/BaseCard.vue";

export default {
  install(app) {
    app.component("BaseButton", BaseButton);
    app.component("BaseCard", BaseCard);

    app.directive("focus", {
      mounted(el) { el.focus(); }
    });
  }
};

After app.use(uikit), every template can use <BaseButton>, <BaseCard>, and v-focus without imports.

Share Data with provide and inject

Global properties do not work inside <script setup>, because there is no this. A plugin that offers its feature through provide works everywhere, and components fetch it with inject.

// plugins/toast.js
export default {
  install(app) {
    const toast = {
      show(message) { alert(message); }
    };
    app.provide("toast", toast);
  }
};

// Any component
import { inject } from "vue";
const toast = inject("toast");
toast.show("Saved successfully");

Diagram: Two Ways to Reach a Plugin

Options API:   this.$greet("Maya")        (globalProperties)
script setup:  inject("toast").show(...)  (provide and inject)

Plugin Options

The second argument of app.use carries settings. A plugin can read them, apply defaults, and stay flexible.

install(app, options = {}) {
  const duration = options.duration ?? 3000;
  app.provide("toastDuration", duration);
}

Best Practices

  • Create a plugin only for features that many components need. A single component rarely needs one.
  • Prefix global names with $ to avoid clashes with component data.
  • Prefer provide over global properties in new code, since it supports <script setup> and TypeScript.
  • Keep each plugin focused on one feature and document its options.

Summary

Plugins extend an entire Vue application from one installation point. A plugin is an object with an install method or a function that receives the app and options. Plugins add global properties, components, directives, and provided values. Official tools like the router and Pinia use the same pattern, and your own plugins can follow it.