Skip to content

Channels (Pub/Sub)

Pulsabase Channels provide a dedicated pub/sub messaging layer for application events that aren’t tied to database mutations — things like typing indicators, cursor sharing, or real-time notifications.

import pb from './pulsabase';
const chat = pb.channel('chat-room-123');
// Subscribe to events on this channel
chat.on('message', (data) => {
console.log(`${data.user}: ${data.message}`);
});
// Publish an event to all subscribers
chat.send('message', { user: 'Jane', message: 'Hello!' });
Use CaseExample Channel Name
Chat roomschat-room-{roomId}
Typing indicatorstyping-{roomId}
Cursor sharingcursors-{documentId}
Presence (who’s online)presence-{roomId}
Push notificationsnotifications-{userId}
Live pollspoll-{pollId}
const room = pb.channel(`typing-${roomId}`);
// Broadcast that the current user is typing
async function onKeyPress() {
const user = await pb.auth.getUser();
room.send('typing', { userId: user.sub, name: user.given_name });
}
// Show typing indicator to other users
room.on('typing', ({ userId, name }) => {
if (userId !== currentUserId) {
showTypingIndicator(name);
}
});
const presence = pb.channel(`presence-${roomId}`);
// Announce join
const user = await pb.auth.getUser();
presence.send('join', { userId: user.sub, name: user.given_name });
// Track who's online
const onlineUsers = new Map();
presence.on('join', ({ userId, name }) => {
onlineUsers.set(userId, name);
renderOnlineList(onlineUsers);
});
presence.on('leave', ({ userId }) => {
onlineUsers.delete(userId);
renderOnlineList(onlineUsers);
});
// Broadcast leave on disconnect
window.addEventListener('beforeunload', () => {
presence.send('leave', { userId: user.sub });
});

Channel names are arbitrary strings. Choose a naming convention that makes sense for your application, typically using a type prefix and an identifier:

  • chat-{roomId}
  • doc-{documentId}
  • user-{userId}