Modern users expect instant feedback. They want to see notifications without refreshing. They want chat messages to appear immediately. They expect live dashboards to tick up in real-time.
Building these features once required complex WebSocket management. You had to handle handshakes, heartbeats, and connection drops manually. Laravel Echo changed that. It provides an expressive API for subscribing to channels and listening for events.
Echo acts as the bridge between your server and the browser. It works seamlessly with your existing backend logic. You broadcast an event in PHP. Echo catches it in JavaScript. The UI updates instantly.
The Echo Ecosystem: Choosing a Driver
Echo is the frontend client. It needs a backend server to broadcast those messages. You have three primary choices today.
Laravel Reverb is the newest addition. It is a first-party, high-performance WebSocket server written in PHP. It scales to thousands of connections with minimal overhead. It is built specifically for the Laravel ecosystem.
Pusher and Ably are managed alternatives. They handle the infrastructure for you. You pay a fee as your traffic grows. They are excellent for teams that want zero server maintenance.
Your choice of driver won't change how you use Echo. The API remains consistent across all of them. This allows you to swap drivers as your application grows.
Backend: Preparing Your Events
Real-time starts on the server. You must define which events should be broadcast. Laravel makes this straightforward with the ShouldBroadcast interface.
Create an event using the Artisan command. Implement the interface. Define the data you want to share.
namespace App\Events;
use App\Models\Order;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class OrderStatusUpdated implements ShouldBroadcast
{
use SerializesModels;
public $order;
public function __construct(Order $order)
{
$this->order = $order;
}
public function broadcastOn()
{
return new PrivateChannel("orders.{$this->order->id}");
}
}
Laravel automatically serializes public properties. The order object will be sent as a JSON payload. You control the destination using the broadcastOn method.

Private Channels: Securing Your Data
Not every message is for everyone. Private channels ensure data only reaches authorized users. You define these rules in routes/channels.php.
Broadcast::channel('orders.{orderId}', function ($user, $orderId) {
return $user->id === Order::find($orderId)->user_id;
});
This callback returns a boolean. If it returns true, the user can join. If false, Echo will fail to subscribe. This keeps your sensitive updates behind a secure wall.
Echo handles the authentication handshake automatically. It sends a request to your server when you attempt to join a private channel. You don't need to write manual AJAX calls for authorization.
Frontend: Setting Up the Client
Installing Echo is a single command. Most developers pair it with the Pusher JS library, even when using Reverb.
npm install --save laravel-echo pusher-js
Configure the client in your bootstrap.js file. Use environment variables to keep your keys secure.
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT,
forceTLS: false,
enabledTransports: ['ws', 'wss'],
});
Once initialized, window.Echo is available globally. You can now subscribe to your channels and act on incoming events.
Presence Channels: Seeing Who is Online
Presence channels build on private channels. They tell you who else is currently viewing the page. This is essential for collaborative tools and chat applications.

window.Echo.join(`chat.${roomId}`)
.here((users) => {
console.log('Currently online:', users);
})
.joining((user) => {
console.log(`${user.name} joined the room.`);
})
.leaving((user) => {
console.log(`${user.name} left the room.`);
});
The here method provides the initial list of users. The joining and leaving hooks let you update your UI dynamically as people come and go. It creates a sense of community within your app.
Client Whispers: Transient Interactions
Sometimes you need to send data without hitting the database. "User is typing" indicators are the perfect example. Laravel Echo calls these "whispers."
Whispers are client-to-client messages. They bypass the Laravel application logic entirely. They travel through the WebSocket server to other subscribers on the same channel.
// Sending a whisper
channel.whisper('typing', {
name: user.name
});
// Listening for a whisper
channel.listenForWhisper('typing', (e) => {
console.log(`${e.name} is typing...`);
});
These events are lightweight. They don't require server-side event classes. They are designed for high-frequency, low-importance data.
Performance: Scaling with Reverb
As your application grows, connection management becomes a challenge. Traditional PHP processes are not designed for long-lived connections. This is why Laravel Reverb is a game-changer.

Reverb is horizontally scalable. It uses a custom binary protocol for speed. It integrates directly with Laravel Forge for easy deployment.
By offloading connection management to a dedicated process, your main web server stays fast. You can handle thousands of concurrent users without breaking a sweat.
Model Broadcasting: Automating Updates
Laravel can broadcast events automatically when a model changes. This removes the need for manual event classes in many cases.
Add the BroadcastsEvents trait to your model. Define which actions should trigger a broadcast. Echo can then listen for Created, Updated, or Deleted events directly.
This pattern is exceptionally powerful for simple CRUD applications. Your list views can stay in sync with the database with almost zero extra code.
Framework Integrations: React, Svelte, and Livewire
Laravel Echo isn't limited to plain JavaScript. Official packages like @laravel/echo-react and @laravel/echo-svelte provide idiomatic hooks and stores.
If you prefer staying in PHP, Livewire has first-class Echo support. You can listen for events directly inside your components.
protected $listeners = ['echo:orders,OrderShipped' => 'notifyOrder'];
public function notifyOrder($payload)
{
$this->dispatch('show-toast', message: 'Order Shipped!');
}
This deep integration allows you to build sophisticated real-time interfaces without leaving your favorite stack.
The Next Wave of Real-Time
Real-time is no longer a luxury. It is a baseline expectation for modern web applications. Laravel Echo provides the tools to meet that expectation without the headache.
Start with a simple public channel. Move to private channels as you need security. Explore presence channels for collaboration. The ecosystem is designed to grow with you.
We'd love to hear what you're building with Echo. Whether it's a small internal tool or a global SaaS, real-time events will make it feel alive.