Vue.js 3 Event Bus

This guide shows how to use mitt to implement an event bus in Vue 3 and discusses recommended alternatives for scalable app communication.

In Vue 2, developers often used an event bus (a new Vue instance) to send and listen for events across components. However, this pattern was removed in Vue 3 to encourage clearer, more maintainable communication. Let’s see how to safely implement an event bus in Vue 3 using the Composition API.

Creating a Vue 3 Event Bus with mitt

The most recommended way to create an event bus in Vue 3 is by using mitt, a tiny functional event emitter.

Step 1 – Install mitt

npm install mitt

Step 2 – Create the Event Bus

// eventBus.jsimport mitt from 'mitt'   const emitter = mitt() export default emitter

Step 3 – Register it globally

import { createApp } from 'vue'import App from './App.vue' import emitter from './eventBus'   const app = createApp(App) app.config.globalProperties.emitter = emitter app.mount('#app')

Step 4 – Emit and listen to events in components:

<!-- ComponentA.vue -->export default {   mounted() {     this.emitter.emit('custom-event', 'Hello from A')   } }
<!-- ComponentB.vue -->export default {   mounted() {     this.emitter.on('custom-event', (msg) => {       console.log('Received:', msg)     })   } }

Alternative Approaches

Here are the three alternatives:

1. Props and Emits

Use props to send data from parent to child and emits for the reverse.

2. Provide / Inject

Scoped injection of values without prop drilling.
// Parentapp.provide('theme', 'dark')   // Child const theme = inject('theme')

3. Pinia or Vuex

Best for app-wide state and reactive event-driven logic.
Also Read: The Vue JS Advantages In Detail

Best Practices

  • Avoid global event spam – only use for cross-cutting concerns
  • Always clean up listeners – use onUnmounted()
  • Prefer props/events or stores for tightly-coupled or data-rich flows
  • Use descriptive event names – like 'cart:add-item' or 'notification:open'

Key Takeaway

Vue 3 removed the native event bus to improve app structure, but using a library like mitt lets you implement a clean, performant alternative. Keep events scoped and manageable, and always unsubscribe to avoid leaks.

Related Resources

 
Related
Vue

In Vue 3's Composition API, watching for prop changes is essential when you need to respond to updated values passed from a parent component. Unlike…

23 Oct, 2025
Vue

Why You See "Vue is Not a Constructor" This error usually occurs when you're trying to use new Vue() to create an instance, but: Vue…

15 Oct, 2025
Vue

Vue encourages reactive and declarative programming for maintainability. But sometimes direct DOM access is required. In those cases, the $el property gives you access to…

10 Oct, 2025