Test backend WebSocket channels and broadcast events without writing a single line of temporary frontend test code.
Zero throwaway Blade templates. Zero frontend boilerplate. Native support for Laravel Reverb, Pusher, Soketi, and Raw WebSockets.
Key Features β’ Quick Start β’ User Guide & Examples β’ Mock Testing β’ Troubleshooting β’ Credits
When developing real-time features in Laravel (Reverb, Soketi, Pusher):
- The Temporary View Trap: Backend developers write an Event class (
App\Events\OrderCreated) and broadcast channel (orders,private-user.1). To verify that events are actually firing with the expected payload, they are forced to spin up temporary Blade templates (test.blade.php), configure Laravel Echo and Pusher.js in JavaScript, and inspectconsole.log()outputs. - Accidental Git Commits: Temporary test routes, Blade templates, and testing scripts often linger in the codebase and accidentally get committed to version control.
- Frontend Blockers: Frontend engineers have to wait or construct mock listeners just to see what the real backend broadcast payload schema looks like.
EchoScope transforms your browser into a dedicated Broadcast Laboratory:
- Connect directly to your local or remote Reverb server (
127.0.0.1:8080,reverb.yourdomain.com). - Subscribe to Public, Private, and Presence channels with zero frontend setup.
- Automatic Private Channel authentication (
/broadcasting/auth). - Watch events stream in with live formatted, syntax-highlighted JSON payloads.
- 1-Click Copy or Export JSON payloads for immediate frontend handoff.
- β‘ Native Reverb & Pusher Protocol v7: Full protocol handshake, heartbeat ping/pong, and socket ID tracking out of the box.
- ποΈ 2-Column Professional Stream Console:
- Left Sidebar: Channel type selection (
Public,Private,Presence), targeted event filters, active subscription cards, and instant unsubscribe buttons. - Right Console Stream: Real-time log feed, category tabs (
All Logs,Events,Errors,System Info), and live text search.
- Left Sidebar: Channel type selection (
- π Smart Channel Type Auto-Prefixing:
- Type
user.1withPrivateselected β EchoScope automatically translates it toprivate-user.1over the wire, matching standard Laravel Echo conventions. - Type
chat.roomwithPresenceselected β EchoScope automatically prefixespresence-chat.room.
- Type
- π― Targeted Event Filtering: Subscribe to a channel and optionally specify an event filter (e.g.
.OrderCreatedorMessageSent) to only catch the exact events you are debugging. - π 1-Click Copy & JSON Export: Copy any individual payload with one click, or export the entire session log to a
.jsonfile for bug reports and documentation. - π§Ή Memory & Cache Utilities:
Clear Screen UI Logs: Clears in-memory stream without disconnecting.Clear Local Storage Cache: Wipes saved channels and restores default configurations.
- π§ͺ Built-in Mock Laboratory: Run
pnpm run mock-serverto test WebSocket broadcasts without needing a running Laravel installation.
# Clone the repository
git clone https://github.com/sajusun/echo-scope.git
cd echo-scope
# Install dependencies (using pnpm)
pnpm install
# Build the extension bundle
pnpm run buildThe production-ready unpacked extension will be generated in the ./dist folder.
- Open your browser and navigate to
chrome://extensions/ - Enable Developer mode via the toggle switch in the top-right corner.
- Click the Load unpacked button in the top-left corner.
- Select the
distfolder located inside theecho-scopeproject directory:c:\Users\...\echo-scope\dist - π EchoScope is installed! Click the Extensions puzzle icon in Chrome and Pin EchoScope to your toolbar.
Click the Settings Gear Icon (βοΈ) in the sidebar header to open the connection drawer:
| Setting | Default Value | Description |
|---|---|---|
| Protocol | Laravel Reverb |
Protocol dialect (reverb or pusher) |
| Scheme | ws:// |
ws:// for local development, wss:// for SSL/production |
| Host | 127.0.0.1 |
Your Reverb server host (e.g. 127.0.0.1 or localhost) |
| Port | 8080 |
Port where Reverb is running |
| App Key | reverb-key |
REVERB_APP_KEY from your .env file |
| Auth URL | http://your-app.test/broadcasting/auth |
Laravel broadcasting authorization endpoint |
| Bearer Token | (Optional) | Sanctum / Passport token if using API token authentication |
Click Save & Reconnect. The status dot in the bottom footer will turn Green (Echo Service Active).
Use public channels for events that anyone can listen to without authentication.
-
In Laravel: Create an event that broadcasts on a public channel:
namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Queue\SerializesModels; class OrderCreated implements ShouldBroadcast { use SerializesModels; public function __construct(public array $order) {} public function broadcastOn(): array { return [ new Channel('orders'), ]; } public function broadcastAs(): string { return 'OrderCreated'; } }
-
In EchoScope:
- Channel Type: Select
Public - Channel Name:
orders - Event Name (Optional):
OrderCreated(or leave blank to listen to all events) - Click + Subscribe Channel
- Channel Type: Select
-
Trigger Event via Artisan Tinker:
php artisan tinker
broadcast(new \App\Events\OrderCreated([ 'id' => 1042, 'customer' => 'John Doe', 'amount' => 189.50, 'currency' => 'USD', 'status' => 'paid' ]));
-
Result: An
EVENTbadge instantly appears in the EchoScope console stream displaying the channelorders, eventOrderCreated, timestamp, and formatted JSON payload.
Private channels require authorization via Laravel's /broadcasting/auth endpoint.
-
In Laravel: Define channel authorization in
routes/channels.php:use Illuminate\Support\Facades\Broadcast; Broadcast::channel('user.{id}', function ($user, $id) { return (int) $user->id === (int) $id; });
And create the event:
namespace App\Events; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class UserNotificationSent implements ShouldBroadcast { public function __construct(public int $userId, public string $message) {} public function broadcastOn(): array { return [ new PrivateChannel('user.' . $this->userId), ]; } }
-
In EchoScope:
- In Settings (βοΈ), ensure your Auth URL is set (e.g.
http://127.0.0.1:8000/broadcasting/authorhttp://my-app.test/broadcasting/auth). - If using API tokens, enter your Bearer Token.
- If testing in the browser while logged into your Laravel app, session cookies are automatically forwarded!
- Channel Type: Select
Private - Channel Name:
user.1(Note: Do NOT typeprivate-; EchoScope handles prefixing automatically!) - Click + Subscribe Channel
- In Settings (βοΈ), ensure your Auth URL is set (e.g.
-
Trigger Event via Artisan Tinker:
broadcast(new \App\Events\UserNotificationSent(1, 'Your payout has been processed successfully.'));
-
Result: EchoScope sends the socket ID and channel to
/broadcasting/auth, receives the auth signature, completes the subscription, and logs:[INFO] Connecting to private channel: "user.1"...[SUCCESS] Subscribed to private channel: "user.1"[EVENT] UserNotificationSent on private-user.1
Presence channels allow you to see who else is currently subscribed to the channel.
-
In Laravel: Define presence channel authorization in
routes/channels.php:Broadcast::channel('chat.room.{roomId}', function ($user, $roomId) { return [ 'id' => $user->id, 'name' => $user->name, 'avatar' => $user->avatar_url, ]; });
-
In EchoScope:
- Channel Type: Select
Presence - Channel Name:
chat.room.1 - Click + Subscribe Channel
- Channel Type: Select
-
Result: EchoScope authenticates with channel data and logs
subscription_succeededalong with member presence state!
Don't have a Laravel project running right now? You can test EchoScope immediately using the included mock Reverb server:
-
In your terminal, run:
pnpm run mock-server
This starts a standalone WebSocket mock server on
127.0.0.1:8080with mock auth support athttp://127.0.0.1:8080/broadcasting/auth. -
Open EchoScope in Chrome.
-
In Settings (βοΈ), set:
- Host:
127.0.0.1 - Port:
8080 - App Key:
reverb-key - Auth URL:
http://127.0.0.1:8080/broadcasting/auth
- Host:
-
Subscribe to
orders(Public) oruser.1(Private). -
Watch simulated live broadcast events stream in every 3 seconds!
EchoScope (Extension) Laravel Reverb Server
β β
ββββ ws://127.0.0.1:8080/app/{key}?protocol=7 βββββββ>β (Handshake)
β<ββ {"event":"pusher:connection_established"} ββββββββ (Socket ID Received)
β β
[If Private / Presence Channel] β
ββββ POST /broadcasting/auth ββββββββββββββββββββββββ>β (Laravel Auth Controller)
β<ββ {"auth":"key:signature", "channel_data":"..."} βββ
β β
ββββ {"event":"pusher:subscribe","data":{...}} ββββββ>β (Subscription)
β<ββ {"event":"pusher_internal:subscription_succeeded"}β (Subscribed!)
β β
β<ββ {"event":"OrderCreated","data":{...},"channel":..β (Live Broadcast!)
β β
- Make sure Laravel Reverb is running in your terminal:
php artisan reverb:start --debug
- Check that the Port matches your
.env(REVERB_PORT=8080). - If you are running Herd, Valet, or Docker, ensure
127.0.0.1:8080is reachable.
- Ensure the Auth URL is reachable from your browser (e.g.
http://my-app.test/broadcasting/auth). - If your Laravel app requires an authenticated session, ensure you are logged into the app in the same browser profile, or supply a valid API Bearer Token in the EchoScope connection drawer.
- In Laravel, by default events are prefixed with
App\Events\. In frontend Laravel Echo, developers often prefix with a dot (e.g..OrderCreated). - EchoScope supports both formats: leave the event filter blank to receive all events, or specify
.OrderCreatedto match exact event names.
echo-scope/
βββ manifest.json # Chrome Extension Manifest V3
βββ package.json # pnpm build pipeline & scripts
βββ tsconfig.json # TypeScript strict configuration
βββ mock-server.js # Standalone mock Reverb & Auth server
βββ scripts/
β βββ build.js # Multi-target bundler (Vite + Rollup)
β βββ generate-icons.js # Zero-dependency radar icon generator
βββ public/icons/ # High-resolution 16, 32, 48, 128px PNG icons
βββ src/
β βββ types/index.ts # Protocols, log categories, channel types
β βββ engine/
β β βββ reverb-client.ts # Pusher Protocol v7 client engine
β β βββ raw-client.ts # Generic WebSocket client
β β βββ auth-service.ts # /broadcasting/auth signature resolver
β βββ popup/
β β βββ popup.html # 2-Column broadcast console markup
β β βββ popup.css # Terminal UI, badges, ultra-thin scrollbars
β β βββ popup.ts # Console streams, active channel manager
β βββ background/
β βββ index.ts # Service worker
βββ dist/ # Production unpacked extension for Chrome
EchoScope is architected and built with β€οΈ by:
- π Portfolio & Website: https://sajusun.github.io
- π GitHub: @sajusun
- πΌ Role: Full-Stack & Developer Tooling Engineer
- π¬ Repository: https://github.com/sajusun/echo-scope
This project is licensed under the MIT License - feel free to use it in your personal and commercial workflows. Contributions and pull requests are warmly welcomed!