Coming from Supabase Realtime

Concept mapping

Supabase Realtimesvelte-realtime
channel.on('INSERT', cb)live.stream() with merge: 'crud'
channel.on('UPDATE', cb)Same stream, updated events
channel.on('DELETE', cb)Same stream, deleted events
Postgres Changesctx.publish() from your DB layer
Presencemerge: 'presence' + lifecycle hooks
Broadcastctx.publish()
supabase.channel('room')Dynamic topics: (ctx, roomId) => 'room:' + roomId
Row Level Securityupgrade() + guard() + access option
realtime.setAuth(token)upgrade({ cookies })

Side-by-side: Listening to database changes

Supabase Realtime

const channel = supabase.channel('todos')
  .on('postgres_changes', {
    event: 'INSERT',
    schema: 'public',
    table: 'todos'
  }, (payload) => {
    todos = [...todos, payload.new];
  })
  .on('postgres_changes', {
    event: 'DELETE',
    schema: 'public',
    table: 'todos'
  }, (payload) => {
    todos = todos.filter(t => t.id !== payload.old.id);
  })
  .subscribe();

svelte-realtime

// src/live/todos.js
export const addTodo = live(async (ctx, text) => {
  const todo = await db.todos.insert({ text });
  ctx.publish('todos', 'created', todo);
  return todo;
});

export const todos = live.stream('todos', async () => {
  return db.todos.all();
}, { merge: 'crud', key: 'id' });
<script>
  import { todos } from '$live/todos';
</script>

{#each $todos as todo (todo.id)}
  <p>{todo.text}</p>
{/each}

Key differences

  • No Supabase dependency. svelte-realtime runs on your own server. You own the WebSocket connection, the data layer, and the infrastructure.
  • Explicit publishing. Supabase listens to Postgres WAL. svelte-realtime publishes explicitly from your RPC handlers - you control exactly when and what gets broadcast.
  • Merge strategies. Supabase gives you raw INSERT/UPDATE/DELETE payloads. svelte-realtime merges them into a store automatically.
  • RPC built in. Supabase Realtime is read-only - writes go through the REST API or client library. svelte-realtime combines reads and writes in one WebSocket connection.

Migration steps

  1. Replace supabase.channel() subscriptions with live.stream() definitions
  2. Move write operations from Supabase client calls to live() RPC handlers
  3. Add ctx.publish() calls after each database write
  4. Replace Supabase Presence with merge: 'presence' + lifecycle hooks
  5. Replace Row Level Security with upgrade() + guard() for auth

Was this page helpful?