Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Broadcasting Laravel Package

crustum/broadcasting

Lightweight broadcasting package for Laravel that lets you push real-time events to your frontend without a third-party service. Simple setup, integrates with Laravel's event system, and keeps live updates easy to manage in any app.

View on GitHub
Deep Wiki
Context7

Getting Started

This package wires Eloquent-backed "table" classes into Laravel's broadcasting layer so row/table changes can be pushed to the frontend without hand-rolling events.

Minimal path to first broadcast:

composer require <vendor>/<package>   # 1.1.0+
php artisan vendor:publish --tag=<package>-config
  1. Look at BroadcastingBehavior first. As of 1.1.0 it is a thin orchestrator — the actual broadcast logic lives in BroadcastingTrait. Reading the behavior will only tell you when things fire; read the trait to understand what is sent.
  2. Look at BroadcastingTraitInterface second. It is the contract your table class must satisfy. It tells you the exact method surface you are opting into, which is the fastest way to understand the package's mental model.
  3. Confirm your queue and broadcast drivers in config/broadcasting.php and config/queue.php. The default path is queued broadcasting; if QUEUE_CONNECTION=sync you'll get confusing synchronous behaviour in tests.

First use case — broadcasting a table refresh:

use Vendor\Package\Behaviors\BroadcastingBehavior;
use Vendor\Package\Concerns\BroadcastingTrait;
use Vendor\Package\Contracts\BroadcastingTraitInterface;

class OrdersTable extends BaseTable implements BroadcastingTraitInterface
{
    use BroadcastingTrait;

    protected array $behaviors = [
        BroadcastingBehavior::class,
    ];
}

That is the whole 1.1 setup. If you are upgrading from 1.0, the trait and interface are now mandatory — see Gotchas.

Implementation Patterns

Table class as the unit of composition. Keep broadcasting config on the table class, not on models. The behavior reads from the table, so channel names, payload shaping, and enabling/disabling belong there. This makes it trivial to have two tables over the same model broadcast to different channels.

Queue-first broadcasting. Let the behavior enqueue; don't call broadcast helpers inline from controllers or observers. This keeps request latency flat and gives you retries for free. Run a worker in every environment where the UI expects live updates — including staging, or your QA will file "broadcast doesn't work" bugs that are really "no worker running."

Test with TestQueueAdapter, not with a fake broadcaster. This is the headline feature of 1.1.0 and it is the correct way to assert on broadcasts without asserting on Laravel's event bus internals:

use Vendor\Package\Testing\TestQueueAdapter;

public function test_order_table_broadcasts_on_update(): void
{
    $adapter = new TestQueueAdapter();
    // bind/inject the adapter per the package docs

    $this->ordersTable->refresh();

    $this->assertBroadcastQueued();
    $this->assertBroadcastQueuedToChannel('orders.42');

    $this->ordersTable->refreshQuietly();
    $this->assertNoBroadcastsQueued();
}

Use assertBroadcastQueuedToChannel when channel routing is the thing most likely to regress (multi-tenant apps, per-user dashboards). Use assertNoBroadcastsQueued as a guard on quiet/no-op paths — it catches accidental broadcasts from observers firing on unrelated saves, which is the most common production incident with this kind of package.

Layer authorization explicitly. Broadcasting to private/presence channels means channel authorization callbacks in routes/channels.php are load-bearing. A table broadcasting to orders.{id} needs a matching authorization rule; the package will happily broadcast to a channel nobody is allowed to listen to, and you'll debug it as a frontend problem.

Pair with Echo on the client. The package's job ends at the queue. Subscribe with Echo.private('orders.42').listen('.table.updated', ...) and treat the payload as a signal to refetch, not as authoritative state. Partial payloads plus a refetch is more robust than trying to keep the broadcast payload and the client model in sync.

Compose behaviors deliberately. Broadcasting sits alongside your other behaviors in the $behaviors array. Order matters if behaviors mutate the payload; keep broadcasting last unless you have a reason otherwise.

Gotchas and Tips

The 1.0 → 1.1 breaking change is silent at runtime. Tables that used BroadcastingBehavior without BroadcastingTrait + BroadcastingTraitInterface will fail — but depending on how the behavior resolves, this can surface as a TypeError, a missing-method fatal, or (worst case) a behavior that registers and simply never broadcasts. Audit every table class with a grep before deploying:

grep -rl "BroadcastingBehavior" app/ | xargs grep -L "BroadcastingTraitInterface"

If that returns anything, you have a broken table.

PHPUnit 12.5 requires PHP 8.3+. If your app is on 8.2, the package's test suite is not installable and TestQueueAdapter may not be usable in your own tests without version pinning. Check composer why-not phpunit/phpunit 12.5 before assuming the upgrade is a no-op.

Trait boot methods and collisions. Laravel's trait boot convention (bootBroadcastingTrait) means initialization happens automatically, but if your base table class already defines a method with the same name as one in the trait, PHP will fatal on the class, not at the call site. When a table explodes after adding the trait, diff the trait's method list against your base class first.

sync queue hides ordering bugs. With sync, broadcasts fire inline and always appear in the order you wrote them. On Redis/SQS they may not. If ordering matters for your UI, include a sequence or timestamp in the payload and let the client discard stale updates — do not assume FIFO.

Debugging "nothing is broadcast": check in this order — (1) is the worker running, (2) is the behavior actually in $behaviors, (3) does the table implement the interface, (4) is the channel authorization rejecting the client (check laravel.log for 403s on /broadcasting/auth), (5) is BROADCAST_CONNECTION set to something other than log. The log driver is the single most common cause of "it works locally but not in staging."

Extension points. The trait is the intended seam. Override individual methods (payload shaping, channel resolution) in your table class rather than editing the behavior or publishing/vendoring the package. Because the logic now lives in the trait, your overrides are stable across patch releases — this is a genuine improvement over 1.0's behavior-encapsulated logic.

Don't reach for TestQueueAdapter in feature tests that also assert HTTP responses. It swaps queue behaviour, which can mask real dispatch failures. Keep broadcast assertions in focused unit/integration tests and let feature tests exercise the real queue driver with Queue::fake().

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core