← Back to blog
MIGRATION GUIDE6 min read

Migrate from Pusher to NoLag

HB
Henco Burger
July 29, 2026

Pusher Channels popularised hosted realtime pub/sub, and a lot of apps still run on it. If you are moving to NoLag, the good news is that the mental model is almost identical: you subscribe to a channel, you bind to events, and a publisher sends data to everyone listening. This guide maps Pusher concepts onto NoLag and shows the same subscribe-and-publish flow in both.

Why teams move

NoLag keeps the pub/sub foundation you already rely on and adds a few things Pusher does not focus on:

  • Blueprint SDKs for chat, notifications, dashboards, tracking, and more, so common patterns are a few lines instead of a from-scratch build.
  • A coordination layer for AI agents: dispatch work, share state, observe decisions, and gate actions with human approval, on the same infrastructure as your app.
  • Per-message QoS on the broker hop, and presence built in.

Concept map

PusherNoLag
App key + clusterApp (a container for rooms and topics)
ChannelRoom + topic
channel.bind('event', cb)room.on('topic', cb)
pusher.trigger('channel', 'event', data)room.emit('topic', data)
Presence channelPresence (per room)
Private channel + auth endpointActors, access tokens, and per-topic ACL

Before: Pusher

import Pusher from 'pusher-js'

const pusher = new Pusher('APP_KEY', { cluster: 'eu' })

const channel = pusher.subscribe('chat')
channel.bind('message', (data) => {
  console.log('Received:', data)
})

// On your server, using the pusher server SDK:
// pusher.trigger('chat', 'message', { text: 'Hello!' })

After: NoLag

import { NoLag } from '@nolag/js-sdk'

// Create the app and its `general` room in the control plane first. The app
// slug you get back has a random suffix (for example `chat-a3f9`): that is
// what you pass to setApp(). Room slugs are kept verbatim.
const APP_SLUG = 'chat-a3f9'

// Browser: subscribe as one actor
const client = NoLag('your_access_token')
await client.connect()

const room = client.setApp(APP_SLUG).setRoom('general')
room.subscribe('message')
room.on('message', (data) => {
  console.log('Received:', data)
})

// Server (or any other authorised actor): publish. Publishers never receive
// their own messages, so publish from a different actor than the one listening.
const server = NoLag('service_access_token')
await server.connect()
server.setApp(APP_SLUG).setRoom('general').emit('message', { text: 'Hello!' })

The shape is the same. The main differences are that NoLag groups topics inside a room (so you get natural namespacing and presence per room), access is controlled with actors and tokens rather than a per-channel auth endpoint, and any authorised actor can publish from the client side, not only your server. A NoLag publisher never hears its own message back, so append it to your UI locally when you send.

Auth: delete your auth endpoint

Pusher private and presence channels call back to an auth endpoint you host, on every subscribe. NoLag does not need one. A connection authenticates once with an actor access token, and what that actor can read or write is enforced at the broker with per-topic ACL, so there is no per-subscribe round-trip to your server. Every credential resolves to a typed actor: user, device, service, session, agent, orchestrator or observer.

For browser clients, mint a short-lived JWT (client token) on your backend, signed with a project signing key. No NoLag API call is needed to issue one, and it expires on its own within minutes, so a long-lived secret never reaches the browser.

Presence

Pusher presence channels map to NoLag presence, tracked per room. A client joins the member list by calling room.setPresence(data), and everyone else gets presence:join, presence:leave and presence:update events on the client, plus room.fetchPresence() for the current member list, without standing up your own tracking.

Next steps

  • Follow the 5-minute quick start to connect for the first time.
  • If you are building chat, the chat blueprint gives you rooms, who-is-online presence, typing indicators and streamed messages out of the box. It keeps an in-memory cache of the messages it has seen; message history is yours to store.
  • Compare the platforms in more detail: NoLag vs Pusher.