pusher-js in the browser and the official Pusher server
libraries on the backend — work against TeleQuick unchanged. You migrate an
existing Pusher app by pointing the client at the TeleQuick host. One URL.
No SDK swap, no protocol rewrite, no re-learning the channel model.
Reach for it for live dashboards, presence (“who’s here”), in-app notifications,
activity feeds, and collaborative UIs — anywhere a browser needs a durable,
low-latency stream of events without you standing up or operating a socket
cluster.
The one-URL migration
If you already have a Pusher app, the whole migration is the connection config. Keep your channel names, your client event handlers, your auth endpoint, and your server-sidetrigger() calls. Change where the client connects.
App credentials —
app_id, key, and secret — are created in the
Realtime Console. Mint a key there, drop it into
the config above, and you’re connected.Two clients: pusher-js or the QUIC-native SDK
You connect with one of two first-class clients. Both speak the exact same Pusher protocol, use the same channels/events/presence API, the same auth endpoint, and the same server-side publish — so this is purely a client-side choice, and you can even run different clients per platform against one app.Stock pusher-js (WebSocket)
Unmodified
pusher-js over wss://realtime.telequick.dev/app/<key>. The
true zero-change path: no new dependency, no import swap — just repoint
wsHost. Every official Pusher SDK works as-is. Best when you want a pure
drop-in migration on normal, wired networks.TeleQuick QUIC-native client
A drop-in, pusher-js-API-compatible client from the TeleQuick SDK.
Same constructor, same channels/events/presence — but it prefers
WebTransport/QUIC and automatically falls back down a transport ladder. Best
when clients live on lossy, mobile, or high-latency networks.
Comparison
| Client | Transport | When to use |
|---|---|---|
Stock pusher-js | WebSocket (ws / wss) | Pure drop-in migration; no new dependency; normal/wired networks where WebSocket-over-TCP is already fine. |
| TeleQuick QUIC-native client | Ladder: webtransport → ws → sockjs | Mobile / lossy / high-latency clients that need faster reconnects and no TCP head-of-line blocking. |
| TeleQuick native mobile SDK | Raw QUIC | Native iOS/Android apps that want QUIC end-to-end without a browser WebTransport hop. |
Using the QUIC-native client
The QUIC-native client is a separate first-party package — a drop-in replacement for thepusher-js import. It ships in the TeleQuick SDK under the realtime
subpath and exposes a Pusher-compatible constructor, so the only line that
changes is the import.
/app/<key> handler as WebSocket. If WebTransport can’t be
established, the client transparently steps down to ws, and finally to
sockjs, so a connection is always made — you don’t write any fallback logic.
When the QUIC client actually helps — honestly. On a clean, wired network,
WebSocket-over-TCP is already fast and reliable; the QUIC-native client won’t
make it meaningfully faster. Where it wins is lossy, mobile, and high-latency
networks: QUIC avoids TCP head-of-line blocking (one lost packet doesn’t stall
every channel) and reconnects faster via 0-RTT session resumption. Recommend
stock
pusher-js for a straight drop-in migration, and switch the clients that
matter — the mobile and flaky-network ones — to the QUIC-native client.The browser WebTransport server plane is live. Raw QUIC end-to-end (no
WebTransport hop) is the native mobile SDK path; adopt it through the
TeleQuick native iOS/Android SDK rather than a browser bundle. If you’re
unsure whether the native raw-QUIC path fits your app, start on the QUIC-native
browser/JS client — the channel code is identical either way.
The channel model
Same three channel types as Pusher, with the same naming conventions and the same authorization rules. The channel prefix selects the behavior.Public
Any client may subscribe. No authorization. Use for open broadcast — public
status, live scores, anything that isn’t per-user.
Private
Named
private-*. Subscription is HMAC-signed by your auth endpoint, so
only authorized clients can join. Use for per-user or per-tenant streams.Presence
Named
presence-*. A private channel that also tracks membership — each
subscriber contributes member info, and everyone gets a live who-is-here
roster with add/remove events.Authorizing private and presence channels
Private and presence subscriptions are authorized exactly as they are with Pusher: the client asks your server to sign the subscription, and the signed token is validated against your app secret. Pointpusher-js at your existing
auth route and it just works.
authorizeChannel()
(or authenticate() on older versions) — no changes to the signing logic.
Client events
On private and presence channels, clients can emit client events (names prefixedclient-*) that fan out to the other subscribers without a server
round-trip. Ideal for ephemeral, high-frequency signals — typing indicators,
cursor positions, live drawing — where you don’t need the event to touch your
backend. Client events are not allowed on public channels, matching Pusher.
The transport ladder
Whichever client you pick, the wire semantics — channels, events, auth, client events — are identical, and they ride the same/app/<key> handler on
TeleQuick. What differs is which transport carries them:
WebTransport / QUIC
The QUIC-native client’s preferred rung. In the browser this is WebTransport
over HTTP/3; native mobile SDKs can take raw QUIC. This is the rung that pays
off on lossy and mobile networks.
WebSocket
Stock
pusher-js uses this directly, and the QUIC-native client falls back
to it when WebTransport can’t be established. wss://realtime.telequick.dev/app/<key>.Start on WebSocket for a drop-in migration. Move latency- or mobility-sensitive
clients to the QUIC-native client later — your channel code, auth, and server
publish don’t change.
Publishing from your server
Server-side publishing is the Pusher server library, pointed at TeleQuick. Configure it with your app credentials and host, then calltrigger().
- Node
- Python
- REST
Webhooks
Realtime can notify your backend about channel lifecycle over signed webhooks — channel occupied / channel vacated, and on presence channels member added / member removed. Configure them in the Realtime Console.Under the hood
Your events fan out across many shards and nodes in an edge mesh, so a channel’s subscribers can be spread across the fleet and still see every event in order. You don’t operate any of it — there’s no socket cluster, no presence store, and no fan-out tier for you to run. It’s the same operational story shared with the other modalities: connect a client, publish, and the mesh does the delivery.Shipped today: public channels,
private-* with HMAC subscription auth,
presence-* with membership, client-* events, and REST publish. These are the
core and are production-ready. Newer webhook/batch conveniences are noted as
preview above.Related
SDK & API
The full
pusher-js client, server publish, and auth surfaces against
TeleQuick.Console
Create app keys, watch live channel stats, and wire webhooks — no code.
Cookbook
End-to-end, runnable examples: presence rosters, notifications, dashboards.
Recipes
Focused patterns for common realtime UI problems.