# Supabase Queries

> Apply when writing Supabase client queries for CRUD operations, filtering, joins, and real-time subscriptions.

- Skill: `majiayu000/supabase-queries` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add majiayu000/supabase-queries`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/supabase-queries/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/supabase-queries

---


## When to Use

Apply when writing Supabase client queries for CRUD operations, filtering, joins, and real-time subscriptions.

## Patterns

### Pattern 1: Select with Filters
```typescript
// 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
```typescript
// 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
```typescript
// 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)
```typescript
// 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)
```typescript
// 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
```typescript
// 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 `error` before using `data`
- **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

