supabase-queries
Apply when writing Supabase client queries for CRUD operations, filtering, joins, and real-time subscriptions.
When & Why to Use This Skill
This Claude skill streamlines the development of Supabase-integrated applications by providing standardized patterns for CRUD operations, complex relational joins, and real-time data subscriptions. It focuses on optimizing database performance and reliability through best practices in TypeScript/JavaScript client queries, error handling, and efficient data fetching.
Use Cases
- Building real-time collaborative applications that require instant data synchronization via Supabase subscriptions.
- Implementing complex data retrieval logic involving multiple table joins and filtered queries for data-heavy dashboards.
- Optimizing application performance by refactoring inefficient 'Select *' queries into targeted, high-performance data fetches.
- Ensuring robust backend security and reliability by validating Row Level Security (RLS) policies and implementing standardized error handling.
- Accelerating the development of CRUD-based features like user profiles, task management, and content systems with ready-to-use code patterns.
| name | supabase-queries |
|---|---|
| description | Apply when writing Supabase client queries for CRUD operations, filtering, joins, and real-time subscriptions. |
| version | 1.0.0 |
| tokens | ~700 |
| confidence | high |
| - https | //supabase.com/docs/reference/javascript/insert |
| last_validated | 2025-01-10 |
| next_review | 2025-01-24 |
| tags | [supabase, database, queries, javascript] |
When to Use
Apply when writing Supabase client queries for CRUD operations, filtering, joins, and real-time subscriptions.
Patterns
Pattern 1: Select with Filters
// Source: https://supabase.com/docs/reference/javascript/select
const { data, error } = await supabase
.from('todos')
.select('id, title, completed')
.eq('user_id', userId)
.order('created_at', { ascending: false })
.limit(10);
Pattern 2: Insert with Return
// Source: https://supabase.com/docs/reference/javascript/insert
const { data, error } = await supabase
.from('todos')
.insert({ title: 'New todo', user_id: userId })
.select()
.single();
Pattern 3: Update with Match
// Source: https://supabase.com/docs/reference/javascript/update
const { data, error } = await supabase
.from('todos')
.update({ completed: true })
.eq('id', todoId)
.select()
.single();
Pattern 4: Select with Relations (JOIN)
// Source: https://supabase.com/docs/reference/javascript/select
const { data, error } = await supabase
.from('posts')
.select(`
id,
title,
author:profiles(name, avatar_url),
comments(id, content)
`)
.eq('published', true);
Pattern 5: Upsert (Insert or Update)
// Source: https://supabase.com/docs/reference/javascript/upsert
const { data, error } = await supabase
.from('profiles')
.upsert({ id: userId, name: 'New Name' })
.select()
.single();
Pattern 6: Count Query
// Source: https://supabase.com/docs/reference/javascript/select
const { count, error } = await supabase
.from('todos')
.select('*', { count: 'exact', head: true })
.eq('completed', false);
Anti-Patterns
- Not handling errors - Always check
errorbefore usingdata - Select * in production - Specify columns explicitly for performance
- Missing .single() - Use when expecting one row, prevents array return
- Chaining after await - Build query first, then await
Verification Checklist
- Error handling:
if (error) throw error - Specific columns selected (not
*) -
.single()used for single-row queries - RLS policies allow the operation
- Types match database schema