Skip to content
BunBase BunBase BunBase Docs Alpha v0.1.0

Realtime

Four hooks cover WebSocket subscriptions. All unsubscribe automatically on unmount and reconnect transparently via the underlying RealtimeClient.

Subscribe to all changes in a collection.

import { useCollectionEvents } from "@bunbase/react-sdk";
function LiveFeed() {
const { connected } = useCollectionEvents<Post>(
"posts",
(event) => {
console.log(event.event, event.record); // "create" | "update" | "delete"
},
{ invalidateCache: true },
);
return <span>{connected ? "Live" : "Connecting…"}</span>;
}

Subscribe to changes on a specific record. Pass null or undefined to skip.

import { useRecordEvents } from "@bunbase/react-sdk";
function PostDetail({ id }: { id: string }) {
useRecordEvents<Post>("posts", id, (event) => {
if (event.event === "delete") router.navigate("/posts");
});
// ...
}

Low-level hook — subscribe to any channel by name.

import { useRealtime } from "@bunbase/react-sdk";
useRealtime("collection:posts", (event) => { ... });
useRealtime("record:posts:abc123", (event) => { ... });

Accepts a full SubscribeOptions object: events, filter, ids.


Query which user IDs are currently present on a channel.

import { usePresence } from "@bunbase/react-sdk";
function OnlineUsers({ channel }: { channel: string }) {
const { users, refresh } = usePresence(channel);
return (
<ul>
{users.map((uid) => <li key={uid}>{uid}</li>)}
</ul>
);
}

When invalidateCache: true is set on useCollectionEvents or useRealtime, incoming events update the cache intelligently instead of wiping everything:

EventCache action
updatesetData(collection:get:id, record) — detail page updates instantly, zero round-trip. Lists are invalidated and re-fetch in the background.
deleteinvalidate(collection:get:id) + invalidate lists
createInvalidate lists only (can’t safely insert into sorted/filtered lists)

Combine useList with useCollectionEvents to keep a list in sync:

function LivePostList() {
const { data, loading } = useList<Post>("posts", { sort: "-_created_at" });
useCollectionEvents("posts", undefined, { invalidateCache: true });
if (loading) return <p>Loading…</p>;
return <ul>{data?.items.map((p) => <li key={p._id}>{p.title}</li>)}</ul>;
}

Or use the shorthand realtime: true option on useList directly — no useCollectionEvents needed:

const { data } = useList<Post>("posts", { sort: "-_created_at" }, { realtime: true });

Both are equivalent. Use useCollectionEvents when you need an event callback; use realtime: true on useList when you just want cache sync.


useRecord already subscribes to record-level events when an id is provided:

const { data: post } = useRecord<Post>("posts", id);
  • update event → record written to cache, component re-renders immediately (no round-trip)
  • delete event → cache cleared, data becomes undefined