• Fri, Mar 2026

Global Event Bus vs Vuex: Which Should You Use?

Global Event Bus vs Vuex: Which Should You Use?

When you start building Vue.js applications, one of the first challenges you’ll face is how to share data between components. For small apps, it might feel natural to pass props down and emit events up. But as your app grows, this can quickly get messy. Enter two popular solutions: the Global Event Bus and Vuex. But which one should you use, and when?

What is a Global Event Bus?

A Global Event Bus is essentially a Vue instance used solely for communication between components. Instead of props drilling, you can emit events and listen for them globally.

Creating a Global Event Bus


// eventBus.js
import { reactive } from 'vue'

const listeners = reactive(new Map())

export const EventBus = {
  on(event, callback) {
    if (!listeners.has(event)) listeners.set(event, [])
    listeners.get(event).push(callback)
  },
  emit(event, payload) {
    if (listeners.has(event)) {
      listeners.get(event).forEach(cb => cb(payload))
    }
  },
  off(event, callback) {
    if (listeners.has(event)) {
      const index = listeners.get(event).indexOf(callback)
      if (index > -1) listeners.get(event).splice(index, 1)
    }
  }
}

Using the Global Event Bus


<!-- Sender.vue -->
<script setup>
import { EventBus } from './eventBus'

function sendMessage() {
  EventBus.emit('message', 'Hello from Sender!')
}
</script>

<template>
  <button @click="sendMessage">Send Message</button>
</template>

<!-- Receiver.vue -->
<script setup>
import { onMounted } from 'vue'
import { EventBus } from './eventBus'

onMounted(() => {
  EventBus.on('message', msg => {
    alert(`Received: ${msg}`)
  })
})
</script>

<template>
  <p>Waiting for messages...</p>
</template>

This is simple and works well for small applications. But as your app grows, it becomes harder to track what’s being emitted and who’s listening. This is where Vuex comes in.

What is Vuex?

Vuex is Vue’s official state management library. It provides a centralized store that all components can access, making state predictable and easier to debug.

Installing Vuex (for Vue 3)


npm install vuex@next

Creating a Vuex Store


// store.js
import { createStore } from 'vuex'

export const store = createStore({
  state: {
    message: ''
  },
  mutations: {
    setMessage(state, msg) {
      state.message = msg
    }
  },
  actions: {
    updateMessage({ commit }, msg) {
      commit('setMessage', msg)
    }
  },
  getters: {
    message: state => state.message
  }
})

Using Vuex in Your App


// main.js
import { createApp } from 'vue'
import App from './App.vue'
import { store } from './store'

createApp(App).use(store).mount('#app')

Sending and Receiving with Vuex


<!-- Sender.vue -->
<script setup>
import { useStore } from 'vuex'

const store = useStore()

function sendMessage() {
  store.dispatch('updateMessage', 'Hello from Sender!')
}
</script>

<template>
  <button @click="sendMessage">Send with Vuex</button>
</template>

<!-- Receiver.vue -->
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()
const message = computed(() => store.getters.message)
</script>

<template>
  <p>Message: {{ message }}</p>
</template>

Global Event Bus vs Vuex: Key Differences

Here’s a quick comparison of the two approaches:

AspectGlobal Event BusVuex
SetupVery simple, no external library neededRequires installation and configuration
ScalabilityHard to maintain in large appsBuilt for large-scale apps
DebuggingDifficult to trace eventsDevTools support and predictable state
Data HandlingEvent-based communication onlyCentralized state management

Real-World Example: Notifications System

Imagine building a notifications system. Here’s how it looks with both approaches.

Using Global Event Bus


<!-- NotificationSender.vue -->
<script setup>
import { EventBus } from './eventBus'

function notify() {
  EventBus.emit('notify', 'New Notification!')
}
</script>

<template>
  <button @click="notify">Send Notification</button>
</template>

<!-- NotificationList.vue -->
<script setup>
import { ref, onMounted } from 'vue'
import { EventBus } from './eventBus'

const notifications = ref([])

onMounted(() => {
  EventBus.on('notify', msg => {
    notifications.value.push(msg)
  })
})
</script>

<template>
  <ul>
    <li v-for="(note, index) in notifications" :key="index">
      {{ note }}
    </li>
  </ul>
</template>

Using Vuex


// store.js
export const store = createStore({
  state: {
    notifications: []
  },
  mutations: {
    addNotification(state, msg) {
      state.notifications.push(msg)
    }
  },
  actions: {
    triggerNotification({ commit }, msg) {
      commit('addNotification', msg)
    }
  },
  getters: {
    notifications: state => state.notifications
  }
})

<!-- NotificationSender.vue -->
<script setup>
import { useStore } from 'vuex'

const store = useStore()

function notify() {
  store.dispatch('triggerNotification', 'New Notification from Vuex!')
}
</script>

<template>
  <button @click="notify">Send Vuex Notification</button>
</template>

<!-- NotificationList.vue -->
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()
const notifications = computed(() => store.getters.notifications)
</script>

<template>
  <ul>
    <li v-for="(note, index) in notifications" :key="index">
      {{ note }}
    </li>
  </ul>
</template>

Which One Should You Use?

The answer depends on your project:

  • Use Event Bus if: Your app is small, you only need occasional event-based communication, and you don’t want the overhead of Vuex.
  • Use Vuex if: Your app is medium-to-large, state is complex, and you need centralized, predictable state management with debugging tools.

Final Thoughts

Both solutions have their place in the Vue ecosystem. The Event Bus is like a quick walkie-talkie: great for simple communication. But when your app turns into a bustling city, you’ll want the organized infrastructure of Vuex. Choose wisely based on your project’s complexity and long-term maintenance goals.

This website uses cookies to enhance your browsing experience. By continuing to use this site, you consent to the use of cookies. Please review our Privacy Policy for more information on how we handle your data. Cookie Policy