PHPackages                             qruto/laravel-wave - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. qruto/laravel-wave

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

qruto/laravel-wave
==================

Painless Laravel Broadcasting with SSE.

0.10.1(1y ago)87048.4k↓15.4%38[5 PRs](https://github.com/qruto/laravel-wave/pulls)MITPHPPHP ^8.2CI passing

Since Aug 1Pushed 4mo ago4 watchersCompare

[ Source](https://github.com/qruto/laravel-wave)[ Packagist](https://packagist.org/packages/qruto/laravel-wave)[ Docs](https://github.com/qruto/laravel-wave)[ Fund](https://revolut.me/slavarazum)[ GitHub Sponsors](https://github.com/qruto)[ RSS](/packages/qruto-laravel-wave/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (21)Versions (20)Used By (0)

    ![Laravel Wave Logo](https://github.com/qruto/laravel-wave/raw/HEAD/art/logo-light.png)

Bring **live** to your application

 [![Build Status](https://github.com/qruto/laravel-wave/actions/workflows/tests.yml/badge.svg)](https://github.com/qruto/laravel-wave/actions/workflows/tests.yml) [![Styles check](https://github.com/qruto/laravel-wave/actions/workflows/styles.yml/badge.svg)](https://github.com/qruto/laravel-wave/actions/workflows/styles.yml) [![Types check](https://github.com/qruto/laravel-wave/actions/workflows/types.yml/badge.svg)](https://github.com/qruto/laravel-wave/actions/workflows/types.yml) [![Refactor code](https://github.com/qruto/laravel-wave/actions/workflows/refactor.yml/badge.svg)](https://github.com/qruto/laravel-wave/actions/workflows/refactor.yml) [![Total Downloads](https://camo.githubusercontent.com/481a1a6e02a88e1d2f49b9d37647d2eab78998d7a3a4d6a51d7240fcf179d36f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f717275746f2f6c61726176656c2d77617665)](https://packagist.org/packages/qruto/laravel-wave) [![Latest Stable Version](https://camo.githubusercontent.com/1b47b17df7884cb4f53123ac18cb4814ce56992c07d0ea445ae327bb49da3134/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f717275746f2f6c61726176656c2d77617665)](https://packagist.org/packages/qruto/laravel-wave)

    ![Laravel Wave Demo](https://github.com/qruto/laravel-wave/raw/HEAD/art/connection-demo-light.png)

Introduction
============

[](#introduction)

Unlock the power of Laravel's [broadcasting system](https://laravel.com/docs/master/broadcasting)with **Wave**. Imagine that real-time server broadcasting is possible over native HTTP without any WebSockets setup. Meet the **[Server-sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)** 🛜 Works seamlessly with Laravel's default `redis` broadcasting driver and supports [Laravel Echo](https://github.com/laravel/echo).

Experience it live with our [demo streaming tweets](https://wave.qruto.dev) 🐤.

> Server-Sent Events (**SSE**) is specially tuned for real-time server-to-client communication.

*Compatible with* [![](https://raw.githubusercontent.com/laravel/echo/master/art/logo.svg)](https://laravel.com/docs/11.x/broadcasting)[![](https://raw.githubusercontent.com/laravel/octane/2.x/art/logo.svg)](https://laravel.com/docs/11.x/octane)[![](https://camo.githubusercontent.com/0e199624f119cedd75725cda4a8ee6569c3f67781aa2069572ce35cd3058374c/68747470733a2f2f686572642e6c61726176656c2e636f6d2f696d616765732f61707069636f6e2e706e67)](https://herd.laravel.com)

🌟 Key Features
--------------

[](#-key-features)

**⚡ Works with native Redis Driver**: Wave seamlessly integrates with Laravel's default `redis` broadcasting driver, ensuring efficient real-time data transfer.

**🔄 Resume From Last**: Connection drops? No problem! Wave intelligently resumes the event stream from the last event, ensuring no crucial data is lost in transit.

**🟢 Live Models**: With a simple interface that respects Laravel's native conventions for [Model Events Broadcasting](https://laravel.com/docs/master/broadcasting#model-broadcasting)and [Broadcast Notifications](https://laravel.com/docs/master/notifications#broadcast-notifications), Wave turbocharges your application with real-time updates.e

**🍃 Resource-Friendly Broadcasting with `pauseInactive`**: This feature maximizes resource efficiency by closing the data stream when user inactive ( such as when the user minimizes the browser) and automatically reopens it upon resumption of visibility. Turned off by default.

**🎛️️ Full Requests Control**: Wave hands you the reins over connection and authentication requests, granting you the freedom to shape your broadcasting setup to your exact requirements.

Installation
------------

[](#installation)

### Laravel 11 or higher

[](#laravel-11-or-higher)

Install the package via Composer at first, then install broadcasting setup:

```
composer require qruto/laravel-wave
php artisan install:broadcasting
```

### Laravel 10 or lower

[](#laravel-10-or-lower)

Install **Wave** on both server and client sides using Composer and npm:

```
composer require qruto/laravel-wave
npm install laravel-wave
```

Then, set your `.env` file to use the `redis` broadcasting driver:

```
BROADCAST_DRIVER = redis
```

Usage
-----

[](#usage)

After installing **Wave**, your server is ready to broadcast events. You can use it with **Echo** as usual or try `Wave` model API to work with predefined Eloquent events.

In Laravel 11 or higher, after `install:broadcasting`, you will find:

- broadcasting channel authorization file in `routes/channels.php`
- broadcasting configuration file in `config/broadcasting.php`
- echo instance in `resources/echo.js`
- *(optional)* **Wave** configuration file in `config/wave.php`

### Manual usage

[](#manual-usage)

Import Laravel Echo with `WaveConnector` and pass it to the broadcaster option:

```
import Echo from 'laravel-echo';

import { WaveConnector } from 'laravel-wave';

window.Echo = new Echo({broadcaster: WaveConnector});
```

  For Laravel 10 or lower, locate Echo connection configuration in *resources/js/bootstrap.js* file. ```
- import Echo from 'laravel-echo';

- import Pusher from 'pusher-js';
- window.Pusher = Pusher;

- window.Echo = new Echo({
-     broadcaster: 'pusher',
-     key: import.meta.env.VITE_PUSHER_APP_KEY,
-     wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
-     wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
-     wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
-     forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
-     enabledTransports: ['ws', 'wss'],
- });
+ import Echo from 'laravel-echo';

+ import { WaveConnector } from 'laravel-wave';

+ window.Echo = new Echo({ broadcaster: WaveConnector });
```

Use Echo as you typically would.

📞 [Receiving Broadcasts](https://laravel.com/docs/master/broadcasting#receiving-broadcasts)documentation.

### Use Live Eloquent Models

[](#use-live-eloquent-models)

With native conventions of [Model Events Broadcasting](https://laravel.com/docs/master/broadcasting#model-broadcasting)and [Broadcast Notifications](https://laravel.com/docs/master/notifications#broadcast-notifications)you can use **Wave** models to receive model events and notifications.

```
import { Wave } from 'laravel-wave';

window.Wave = new Wave();

wave.model('User', '1')
    .notification('team.invite', (notification) => {
        console.log(notification);
    })
    .updated((user) => console.log('user updated', user))
    .deleted((user) => console.log('user deleted', user))
    .trashed((user) => console.log('user trashed', user))
    .restored((user) => console.log('user restored', user))
    .updated('Team', (team) => console.log('team updated', team));
```

Start by calling the `model` method on the `Wave` instance with the model name and key.

By default, Wave prefixes model names with `App.Models` namespace. You can customize this with the `namespace` option:

```
window.Wave = new Wave({namespace: 'App.Path.Models'});
```

📄 [Check out full Laravel Broadcasting documentation](https://laravel.com/docs/11.x/broadcasting)

Configuration
-------------

[](#configuration)

### Client Options

[](#client-options)

These options can be passed to the `Wave` or `Echo` instance:

NameTypeDefaultDescriptionendpoint*string*`/wave`Primary SSE connection route.namespace*string*`App.Events`Namespace of events to listen for.auth.headers*object*`{}`Additional authentication headers.authEndpoint*string?*`/broadcasting/auth`Authentication endpoint.csrfToken*string?*`undefined` or `string`CSRF token, defaults from `XSRF-TOKEN` cookie.bearerToken*string?*`undefined`Bearer tokenfor authentication.request*[Request](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options)?*`undefined`Custom settings for connection and authentication requests.pauseInactive*boolean*`false`If `true`, closes connection when the page is hidden and reopens when visible.debug*boolean*`false`Toggles debug mode. If set to `true`, provides detailed event logs in the console, helping with event diagnosis and troubleshooting.```
new Echo({
    broadcaster: WaveConnector,
    endpoint: '/sse-endpoint',
    bearerToken: 'bearer-token',
    //...
});

// or

new Wave({
    authEndpoint: '/custom-broadcasting/auth',
    csrfToken: 'csrf-token',
})
```

### Server Options

[](#server-options)

You can publish the Wave configuration file with:

```
php artisan vendor:publish --tag="wave-config"
```

Here are the contents of the published configuration file:

```
return [

    /*
    |--------------------------------------------------------------------------
    | Resume Lifetime
    |--------------------------------------------------------------------------
    |
    | Define how long (in seconds) you wish an event stream to persist so it
    | can be resumed after a reconnect. The connection automatically
    | re-establishes with every closed response.
    |
    | * Requires a cache driver to be configured.
    |
    */
    'resume_lifetime' => 60,

    /*
    |--------------------------------------------------------------------------
    | Reconnection Time
    |--------------------------------------------------------------------------
    |
    | This value determines how long (in milliseconds) to wait before
    | attempting a reconnect to the server after a connection has been lost.
    | By default, the client attempts to reconnect immediately. For more
    | information, please refer to the Mozilla developer's guide on event
    | stream format.
    | https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format
    |
    */
    'retry' => null,

    /*
    |--------------------------------------------------------------------------
    | Ping
    |--------------------------------------------------------------------------
    |
    | A ping event is automatically sent on every SSE connection request if the
    | last event occurred before the set `frequency` value (in seconds). This
    | ensures the connection remains persistent.
    |
    | By setting the `eager_env` option, a ping event will be sent with each
    | request. This is useful for development or for applications that do not
    | frequently expect events. The `eager_env` option can be set as an `array` or `null`.
    |
    | For manual control of the ping event with the `sse:ping` command, you can
    | disable this option.
    |
    */
    'ping' => [
        'enable' => true,
        'frequency' => 30,
        'eager_env' => 'local', // null or array
    ],

    /*
    |--------------------------------------------------------------------------
    | Routes Path
    |--------------------------------------------------------------------------
    |
    | This path is used to register the necessary routes for establishing the
    | Wave connection, storing presence channel users, and handling simple whisper events.
    |
    */
    'path' => 'wave',

    /*
     |--------------------------------------------------------------------------
     | Route Middleware
     |--------------------------------------------------------------------------
     |
     | Define which middleware Wave should assign to the routes that it registers.
     | You may modify these middleware as needed. However, the default value is
     | typically sufficient.
     |
     */
    'middleware' => [
        'web',
    ],

    /*
     |--------------------------------------------------------------------------
     | Auth & Guard
     |--------------------------------------------------------------------------
     |
     | Define the default authentication middleware and guard type for
     | authenticating users for presence channels and whisper events.
     |
     */
    'auth_middleware' => 'auth',

    'guard' => 'web',

];
```

Persistent Connection with Nginx + PHP FPM
------------------------------------------

[](#persistent-connection-with-nginx--php-fpm)

Wave is designed to automatically reconnect after a request timeout. During reconnection, you won't lose any events because Wave stores event history for one minute by default and resumes it. You can adjust the duration of event history storage by modifying the `resume_lifetime` value in the config file.

However, if you want to maintain a persistent connection, let's configure your web server.

### `fastcgi_read_timeout`

[](#fastcgi_read_timeout)

By default, the `fastcgi_read_timeout` value is `60s` for Nginx + PHP FastCGI server setup.

#### Option 1. Without changing the `fastcgi_read_timeout` value

[](#option-1-without-changing-the-fastcgi_read_timeout-value)

> Ensure that the interval between events pushed into Wave connection is shorter than the read timeout value

To enhance the certainty of events occurring more frequently than the standard timeout, Wave attempts to send a ping event with each Server-Sent Events (SSE) connection request, provided that the previous event occurred prior to the `ping.frequency`configuration value.

If your application doesn't expect many real-time connections, specify the list of environments in which a ping event will be sent with each Wave connection. By default, this is set to `local`.

#### Option 2. Manual ping control

[](#option-2-manual-ping-control)

To ensure accurate frequency sending a ping event:

1. Disable automatic sending by changing the `ping.enable` config value to `false`
2. Use the `sse:ping` command to manually send a single ping or operate at an interval

Run the command with the `--interval` option to send a ping event at a specified interval in seconds, for example let's send a ping event every `30s`:

```
php artisan sse:ping --interval=30
```

So, every `30s`, the command will send a ping event to all active connections and ensure that the connection remains persistent, because the frequency of sending events is less than `60s`.

Alternatively, use the Laravel [Tasks scheduler](https://laravel.com/docs/master/scheduling#introduction)to send a ping event every minute or more often if `fastcgi_read_timeout` value is greater than `60s`:

```
protected function schedule(Schedule $schedule)
{
    $schedule->command('sse:ping')->everyMinute();
}
```

### `request_terminate_timeout`

[](#request_terminate_timeout)

Some platforms, such as [Laravel Forge](https://forge.laravel.com), configure the PHP FPM pool with `request_terminate_timeout = 60`, terminating all requests after `60s`.

You can disable this in the `/etc/php/8.1/fpm/pool.d/www.conf` config file:

```
request_terminate_timeout = 0
```

or you can configure a separate pool for the SSE connection.

Future Plans
------------

[](#future-plans)

📍 Local broadcasting driver

📥 📤 two ways live models syncing

📡 Something awesome with opened live abilities...

Testing
-------

[](#testing)

```
composer test
```

Support
-------

[](#support)

In light of recent events in Ukraine, my life has taken an unexpected turn. Since February 24th, I've lost my commercial work, my permanent residence, and my ability to plan for the future.

During these challenging times, I derive strength and purpose from creating open source projects, such as Wave.

[![support me](https://raw.githubusercontent.com/slavarazum/slavarazum/main/support-banner.png)](https://github.com/sponsors/qruto)

I welcome you to visit my [GitHub Sponsorships profile](https://github.com/sponsors/qruto). There, you can discover more about my current work, future ambitions, and aspirations. Every ⭐ you give brings joy to my day, and your sponsorship can make a profound difference in my ability to continue creating.

I'm truly grateful for your support, whether it's a shout-out or a heartfelt " thank you".

💳 [Help directly](https://revolut.me/slavarazum).

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md)for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Slava Razum](https://github.com/slavarazum)
- [All Contributors](../../contributors)

Package template based on [Spatie Laravel Skeleton](https://github.com/spatie/package-skeleton-laravel).

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance62

Regular maintenance activity

Popularity53

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 86% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~74 days

Recently: every ~91 days

Total

14

Last Release

423d ago

PHP version history (3 changes)0.5.0PHP ^8.1

0.5.2PHP ^8.0

0.10.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/168def029554d2e57e1bfeadf4a4dcf38152d6415d3b171823a2e1145feb53ed?d=identicon)[Slava Razum](/maintainers/Slava%20Razum)

---

Top Contributors

[![slavarazum](https://avatars.githubusercontent.com/u/5820718?v=4)](https://github.com/slavarazum "slavarazum (148 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (20 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (3 commits)")[![marcomiddeldorff](https://avatars.githubusercontent.com/u/81476563?v=4)](https://github.com/marcomiddeldorff "marcomiddeldorff (1 commits)")

---

Tags

broadcastinglaravellive-updatereal-timessephplaravelsserealtimeserver sent eventsevent sourceqrutolaravel-wavelive-update

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/qruto-laravel-wave/health.svg)

```
[![Health](https://phpackages.com/badges/qruto-laravel-wave/health.svg)](https://phpackages.com/packages/qruto-laravel-wave)
```

###  Alternatives

[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[laragear/preload

Effortlessly make a Preload script for your Laravel application.

119363.5k](/packages/laragear-preload)[psalm/plugin-laravel

Psalm plugin for Laravel

3274.9M308](/packages/psalm-plugin-laravel)[nativephp/mobile

NativePHP for Mobile

82724.0k43](/packages/nativephp-mobile)[tapp/filament-google-autocomplete-field

Filament plugin that provides a Google Autocomplete field

3098.1k](/packages/tapp-filament-google-autocomplete-field)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
