@night-owl-elite/vue3-ws

A scalable and reactive Vue 3 Composition API wrapper for Laravel Echo and WebSockets, featuring automatic lifecycle cleanup, dynamic token injection, and native support for Reverb, Pusher, and Soketi.
1,603
Install
npm install @night-owl-elite/vue3-ws
Latest Version:1.0.10
Vue:3
License:MIT
Last Updated:Jun 16, 2026
Links: npm
Maintainer: nightowl-elite

@night-owl-elite/vue3-ws

A scalable and reactive Vue 3 Composition API wrapper for Laravel Echo and WebSockets, featuring automatic lifecycle cleanup, dynamic token injection, and native support for Reverb, Pusher, and Soketi.

Features

  • No Memory Leaks: Automatically calls .stopListening() and leaves channels when Vue components unmount.
  • Universal Backend Support: Works flawlessly with Pusher Cloud, Laravel Reverb, and Soketi.
  • Dynamic Authentication: Pass token getters (e.g., from Pinia or Vuex) so your WebSocket connection always uses the freshest auth state.
  • Full Channel Support: First-class methods for Public, Private, and Presence channels.
  • Client-to-Client Whispering: Built-in methods for transient states like "User is typing..." indicators.

Installation

Install the package alongside its peer dependencies (laravel-echo and pusher-js):

npm install @night-owl-elite/vue3-ws laravel-echo pusher-js

Getting Started
1. Initialization
Initialize the WebSocket connection once in your application lifecycle. The best place to do this is in your main.js file, or inside your Authentication store after a user logs in.
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import { initializeEcho } from '@night-owl-elite/vue3-ws'

const app = createApp(App)

// Example: Initialize Echo
initializeEcho({
  // Required:
  key: import.meta.env.VITE_PUSHER_APP_KEY,
  cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
  
  // Optional (Required for self-hosting with Laravel Reverb / Soketi):
  host: import.meta.env.VITE_PUSHER_HOST, // e.g., 'localhost'
  port: import.meta.env.VITE_PUSHER_PORT, // e.g., 8080
  scheme: import.meta.env.VITE_PUSHER_SCHEME, // e.g., 'http' or 'https'
  
  // Authentication Configuration:
  authEndpoint: import.meta.env.VITE_WEBSOCKET_ENDPOINT || '/api/broadcasting/auth',
  
  // Dynamic Token Injection (Can be a string or a function)
  // Passing a function ensures Echo always gets the latest token if it changes!
  token: () => localStorage.getItem('auth_token') 
})

app.mount('#app')


2. Usage in Components
Use the useEcho composable anywhere in your Vue 3 application. Because of the built-in automatic lifecycle teardown, you never have to manually clean up your event listeners when a component unmounts.
<script setup>
import { ref } from 'vue';
import { useEcho } from '@night-owl-elite/vue3-ws';

const props = defineProps(['roomId']);

const messages = ref([]);
const onlineUsers = ref([]);
const typingUser = ref(null);
let typingTimeout = null;

const { listenPrivate, whisper, listenWhisper, joinPresence } = useEcho();
const channelName = `chat.${props.roomId}`;

// ----------------------------------------------------
// 1. PRESENCE: Who is online?
// ----------------------------------------------------
joinPresence(channelName, {
  onHere: (users) => { onlineUsers.value = users; },
  onJoin: (user) => { onlineUsers.value.push(user); },
  onLeave: (user) => {
    onlineUsers.value = onlineUsers.value.filter(u => u.id !== user.id);
  }
});

// ----------------------------------------------------
// 2. LISTENING: Get new messages saved to the database
// ----------------------------------------------------
listenPrivate(channelName, '.MessageSent', (event) => {
  messages.value.push(event.message);
});

// ----------------------------------------------------
// 3. WHISPERING: Typing Indicators (Bypasses Database)
// ----------------------------------------------------
const handleTyping = () => {
  // Tell other clients in this private room we are typing
  whisper(channelName, 'typing', { name: 'CurrentUserName' });
};

// Listen for others whispering
listenWhisper(channelName, 'typing', (data) => {
  typingUser.value = data.name;

  // Clear the typing indicator after 2 seconds of silence
  clearTimeout(typingTimeout);
  typingTimeout = setTimeout(() => {
    typingUser.value = null;
  }, 2000);
});
</script>

<template>
  <div class="chat-room">
    </div>
</template>


 API Reference
initializeEcho(config: Object)
Bootstraps the global Laravel Echo instance.

key (String): Pusher/Reverb App Key.

cluster (String): Pusher Cluster.

token (String | Function): Bearer token for private/presence channels. Can be a static string or a callback function returning a string.

host (String): Custom WebSocket host (Required for Reverb/Soketi).

port (Number): Custom WebSocket port (Required for Reverb/Soketi).

scheme (String): http or https (Defaults to https).

forceTLS (Boolean): Force TLS connection (Defaults to true).

authEndpoint (String): The backend URL used to authorize private/presence channels.

useEcho()
Returns the following reactive methods:

echo: The raw Laravel Echo instance (useful if you need advanced Echo features not covered by the wrapper).

listenPublic(channelName, eventName, callback): Subscribe to a public channel.

listenPrivate(channelName, eventName, callback): Subscribe to a private, authenticated channel.

joinPresence(channelName, { onHere, onJoin, onLeave }): Join a presence channel and track online users.

whisper(channelName, whisperName, data): Broadcast client-to-client data without hitting the database.

listenWhisper(channelName, whisperName, callback): Listen for client-to-client broadcasts.

Related Packages

@kirchdev/pinia-colada-plugin-laravel-echo

Pinia Colada plugin that keeps a query's cache current from Laravel Echo events...

1,345 0
@laravel/echo-vue

Vue hooks for seamless integration with Laravel Echo.

1,462,008 1,361
vue-echo

Vue integration for the Laravel Echo library.

46,547 228
@arkstack/realtime

Client for consuming Arkstack realtime notifications (Pusher/Firebase), with fra...

9,305 6
vue-echo-laravel

It's a laravel/echo wrapper for Vue JS ^2.0. This Vue plugin injects a Laravel E...

73,081 20

Version History

Version Released Vue License
1.0.10 ^3.5.33 MIT
1.0.9 ^3.5.33 MIT
1.0.8 ^3.5.33 MIT
1.0.7 ^3.5.33 MIT
1.0.6 ^3.5.33 MIT