Migrate from Pusher to Vask (Laravel). Drop-in host swap.
Vask speaks the Pusher protocol, so a standard Laravel Broadcasting app keeps the pusher connection, laravel-echo, pusher-js, Broadcast events, and channel auth flow. The cutover is credentials plus host.
Migration summary
At a glance
- Type
- Drop-in host swap
- Typical time
- 10-15 minutes
- Server SDK
- pusher-http-php unchanged
- Client SDK
- laravel-echo and pusher-js unchanged
- Auth changes
- verify existing /broadcasting/auth
- Rollback
- restore old Pusher env vars
Files touched
- .env
- config/broadcasting.php
- resources/js/echo.js
Get started
Realtime made simple.
Free Tier: 500K broadcasts/mo and 100 concurrent across unlimited apps. $10/mo when you outgrow it.
Minimal cutover
Save your current Pusher values first. Then change the Laravel broadcast env block. If your app still uses BROADCAST_DRIVER, keep that name and set it to pusher.
BROADCAST_CONNECTION=pusher
-PUSHER_APP_ID=123456
-PUSHER_APP_KEY=abc123
-PUSHER_APP_SECRET=xyz789
-PUSHER_HOST=
+PUSHER_APP_ID=your_vask_key
+PUSHER_APP_KEY=your_vask_key
+PUSHER_APP_SECRET=your_vask_secret
+PUSHER_HOST=wss.vask.dev
PUSHER_PORT=443
PUSHER_SCHEME=https
-PUSHER_APP_CLUSTER=us3
+PUSHER_APP_CLUSTER=mt1
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"If your SDK asks for an app id, use the Vask app key. Vask does not issue a separate customer-facing app id.
Rollback
Put the saved Pusher values back, redeploy or rebuild the client bundle if VITE_PUSHER_* values are baked in, and clear config cache if you cache Laravel config during deploy. Rollback is symmetric because no app code or schema changes are required.
Laravel package shortcut
composer require vask/laravel
php artisan vask:installThe installer writes the same Pusher-compatible env values and runs php artisan vask:doctor. Source: github.com/vask-dev/laravel · packagist.
Server publish
Confirm config/broadcasting.php reads the Pusher host from env:
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
],If host is hardcoded to a Pusher cluster host, change it to read PUSHER_HOST.
Client subscribe
Confirm Echo reads the Vite env values:
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
wsHost: import.meta.env.VITE_PUSHER_HOST,
wsPort: import.meta.env.VITE_PUSHER_PORT,
wssPort: import.meta.env.VITE_PUSHER_PORT,
forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});Private and presence channels
Keep your existing routes/channels.php callbacks and /broadcasting/auth route. Public channels, Echo.private(...), and Echo.join(...) should keep the same names and event listeners.
Verify
- Deploy the env change to staging.
- Confirm the browser opens a WebSocket to
wss.vask.dev. - Trigger one Broadcast event and verify the client receives it.
- Subscribe to one private or presence channel and confirm
/broadcasting/authreturns 200.
Gotchas
- Stale Vite bundle. Server publishes may hit Vask while the browser still connects to Pusher until the client bundle is rebuilt.
- Old cluster assumptions. Keep
PUSHER_APP_CLUSTERonly as a compatibility placeholder;PUSHER_HOST=wss.vask.devroutes traffic. - Custom auth route. If you changed
/broadcasting/auth, make sure Echo still points at the same route after deploy. - Whitespace in secrets. A copied newline in
PUSHER_APP_SECRETusually shows up as private-channel 403s.
Where to go next
- Read the Pusher vs Vask comparison for architecture and pricing context.
- Check the Laravel docs for advanced setup.
- Run the fan-out calculator if cost is the migration driver.
- Can I test the Pusher to Vask cutover in staging first?
- Yes. Create a staging Vask app, apply the .env diff there, rebuild the client bundle, and verify public, private, and presence channels before touching production.
- How do I roll back to Pusher?
- Restore the previous Pusher .env values, rebuild or redeploy anything that embeds VITE_PUSHER_* values, and clear Laravel config cache if your deploy uses it. No event, channel, or database changes are required.
- Can I run Pusher and Vask in parallel?
- The low-risk path is staging first, then a production credential swap. If you need live parallel publishing, add a temporary broadcaster wrapper that fans out each event to both Pusher and Vask, then remove it after verification.
- Do private and presence channels need changes?
- Usually no. Laravel keeps using /broadcasting/auth, private- and presence- channel names, and the same Pusher-compatible auth signature. Verify the auth endpoint returns 200 after the credential swap.
Get going
Keep the events. Swap the endpoint. Verify staging, then move the same env diff to production.
Make the switch
Swap the credentials. Keep the events.
Use Vask credentials, keep your existing Broadcast events, and point the Pusher-compatible config at wss.vask.dev.