Unnamed Skill
Apply when implementing real-time features: live updates, presence, broadcast messages, or database change subscriptions.
$ 安裝
git clone https://github.com/CoderMariusz/MonoPilot /tmp/MonoPilot && cp -r /tmp/MonoPilot/.claude/skills/supabase-realtime ~/.claude/skills/MonoPilot// tip: Run this command in your terminal to install the skill
SKILL.md
name: supabase-realtime description: Apply when implementing real-time features: live updates, presence, broadcast messages, or database change subscriptions. version: 1.0.0 tokens: ~600 confidence: high sources:
- https://supabase.com/docs/guides/realtime
- https://supabase.com/docs/reference/javascript/subscribe last_validated: 2025-01-10 next_review: 2025-01-24 tags: [supabase, realtime, websocket, database]
When to Use
Apply when implementing real-time features: live updates, presence, broadcast messages, or database change subscriptions.
Patterns
Pattern 1: Database Changes Subscription
// Source: https://supabase.com/docs/guides/realtime
import { useEffect } from 'react';
import { supabase } from '@/lib/supabase';
function useRealtimeMessages(roomId: string) {
const [messages, setMessages] = useState<Message[]>([]);
useEffect(() => {
// Initial fetch
supabase.from('messages').select('*').eq('room_id', roomId)
.then(({ data }) => setMessages(data || []));
// Subscribe to changes
const channel = supabase
.channel(`room:${roomId}`)
.on('postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'messages', filter: `room_id=eq.${roomId}` },
(payload) => setMessages((prev) => [...prev, payload.new as Message])
)
.subscribe();
return () => { supabase.removeChannel(channel); };
}, [roomId]);
return messages;
}
Pattern 2: Presence (Who's Online)
// Source: https://supabase.com/docs/guides/realtime/presence
const [onlineUsers, setOnlineUsers] = useState<User[]>([]);
useEffect(() => {
const channel = supabase.channel('online-users');
channel
.on('presence', { event: 'sync' }, () => {
const state = channel.presenceState();
const users = Object.values(state).flat() as User[];
setOnlineUsers(users);
})
.subscribe(async (status) => {
if (status === 'SUBSCRIBED') {
await channel.track({ user_id: currentUser.id, name: currentUser.name });
}
});
return () => { supabase.removeChannel(channel); };
}, [currentUser]);
Pattern 3: Broadcast (Client-to-Client)
// Source: https://supabase.com/docs/guides/realtime/broadcast
const channel = supabase.channel('cursor-positions');
// Send cursor position
const sendCursor = (x: number, y: number) => {
channel.send({
type: 'broadcast',
event: 'cursor',
payload: { x, y, userId: currentUser.id },
});
};
// Receive cursor positions
channel
.on('broadcast', { event: 'cursor' }, ({ payload }) => {
setCursors((prev) => ({ ...prev, [payload.userId]: payload }));
})
.subscribe();
Pattern 4: All Change Events
// Source: https://supabase.com/docs/reference/javascript/subscribe
const channel = supabase
.channel('table-changes')
.on('postgres_changes',
{ event: '*', schema: 'public', table: 'posts' },
(payload) => {
if (payload.eventType === 'INSERT') handleInsert(payload.new);
if (payload.eventType === 'UPDATE') handleUpdate(payload.new);
if (payload.eventType === 'DELETE') handleDelete(payload.old);
}
)
.subscribe();
Anti-Patterns
- No cleanup - Always
removeChannelon unmount - Subscribing to entire table - Use filters to limit data
- No error handling - Handle subscription errors
- Missing RLS - Realtime respects RLS policies
Verification Checklist
- Channel cleanup in useEffect return
- Filters applied to subscriptions
- Initial data fetched before subscribe
- RLS policies allow realtime access
- Error state handling for subscription failures
Repository

CoderMariusz
Author
CoderMariusz/MonoPilot/.claude/skills/supabase-realtime
1
Stars
0
Forks
Updated3d ago
Added1w ago