JavaScript SDK - Realtime#

Subscribe to table changes with two transports:

  • websocket (default) - WebSocket to the realtime server. One persistent connection, auto-reconnect with backoff, event recovery. Recommended for production and multi-table apps.
  • sse - Server-Sent Events stream. Simple, fine for small apps.

Subscribe#

const sub = db.realtime.subscribe(
  'profiles',                        // table to watch
  (event) => {
    event.type;        // 'INSERT' | 'UPDATE' | 'DELETE'
    event.table;       // 'profiles'
    event.record;      // the row
    event.old_record;  // previous row (UPDATE/DELETE)
    event.created_at;
  },
  { events: ['INSERT', 'UPDATE'] },  // optional event filter
);

// Force a transport
db.realtime.subscribe('profiles', cb, { transport: 'websocket' });
db.realtime.subscribe('profiles', cb, { transport: 'sse' });

// Stop listening
sub.unsubscribe();
TypeScript

Typed payloads#

type Message = { message_id: string; message: string; user_id?: string | null; created_at: string };

db.realtime.subscribe<Message>('messages', (event) => {
  event.record.message; // typed
});
TypeScript

How it works#

  1. The SDK calls POST /projects/{id}/realtime/connect and receives a scoped JWT (url, token, channel, 24h validity).
  2. It opens a WebSocket to the realtime server with the token; the token grants exactly one channel.
  3. On disconnect it reconnects with exponential backoff and recovers missed events from the channel history (last 100 events / 10 minutes).

Event payload#

{
  "id": "uuid",
  "type": "INSERT",
  "table": "messages",
  "project_id": "5c73dab0-...",
  "record": { "id": "...", "message": "hello" },
  "old_record": null,
  "created_at": "2026-10-03T20:47:34Z"
}
JSON

Next: Storage.