Skip to Content
Client SDKPresence

Client: Presence

Track who’s online in a room, listen for join/leave events, and share ephemeral presence state (like "typing" or "away").

Need user-level presence across tabs or devices? Use the createPresence utility to group connections by user ID or any other logic.

Subscribing

Subscribe to presence in a room:

const { success, present } = await client.subscribePresence( "lobby", (update) => { if (update.type === "join") { console.log("User joined:", update.connectionId); } else if (update.type === "leave") { console.log("User left:", update.connectionId); } else if (update.type === "state") { console.log("State update:", update.connectionId, update.state); } } );

You’ll receive:

  • A list of currently present connection IDs via present
  • Real-time "join", "leave", and "state" events

Unsubscribe when done:

await client.unsubscribePresence("lobby");

Join + subscribe in one step

Use joinRoom() with a callback to automatically subscribe to presence:

const { success, present } = await client.joinRoom("lobby", (update) => { console.log(update); });

If you omit the callback, present still reflects the current occupants — but you won’t receive real-time updates.

Publishing presence state

Send ephemeral presence state to others in the room:

await client.publishPresenceState("lobby", { state: { status: "typing" }, expireAfter: 8000, // optional (ms) });

Clear it manually:

await client.clearPresenceState("lobby");

Automatic presence refresh

The client automatically refreshes presence every 15 seconds for all rooms you’ve joined.

You don’t need to manually track rooms or re-send updates — Mesh handles it behind the scenes.

Receiving presence states

Presence updates include state events:

const { success, present, states } = await client.subscribePresence( "lobby", (update) => { if (update.type === "state") { console.log(`${update.connectionId} state:`, update.state); } } );

You’ll also get a states object with current values at the time of subscription:

{ "abc123": { status: "typing" }, "def456": { status: "away" } }

Resolving user info

Presence events only include connectionId. To show user names or avatars, fetch metadata:

const metadata = await client.getConnectionMetadata(update.connectionId);

Or resolve metadata for all present connections:

const all = await Promise.all( present.map((id) => client.getConnectionMetadata(id)) ); // [{ userId, username, avatar }, ...]

Want to show only one presence per user?
createPresence

Use cases

  • Online indicators
  • Room occupancy lists
  • Typing indicators
  • Game states like “ready”, “spectating”, etc.

Tips

  • Unsubscribe when no longer needed to reduce overhead
  • Resubscribe after reconnecting
    (or use createPresence, which handles this for you)
  • Use expireAfter for short-lived states like "typing"
  • Debounce frequent updates to avoid spamming the network
Last updated on
© 2025