dev-supabase
Handles Supabase backend development including auth, DB, and storage.
Install
mkdir -p .claude/skills/dev-supabase && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14354" && unzip -o skill.zip -d .claude/skills/dev-supabase && rm skill.zipInstalls to .claude/skills/dev-supabase
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Backend development with Supabase. Trigger when the user wants to configure auth, the database, or Supabase storage.Key capabilities
- →Configure Supabase client for authentication
- →Implement user sign-up, sign-in, and sign-out
- →Define Row Level Security (RLS) policies for database tables
- →Perform database queries (select, insert, update, delete)
- →Upload and retrieve files from Supabase Storage
- →Set up real-time database subscriptions
How it works
This skill provides code examples and best practices for interacting with Supabase services, including authentication, database, and storage APIs.
Inputs & outputs
When to use dev-supabase
- →Configuring RLS policies
- →Setting up Supabase auth
- →Implementing realtime database subscriptions
About this skill
Supabase Development
Configuration
import { createClient } from '@supabase/supabase-js';
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
Authentication
// Sign up
await supabase.auth.signUp({ email, password });
// Sign in
await supabase.auth.signInWithPassword({ email, password });
// OAuth
await supabase.auth.signInWithOAuth({ provider: 'google' });
// Sign out
await supabase.auth.signOut();
Database with RLS
-- Enable RLS
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
-- Policy: users can read own data
CREATE POLICY "Users read own profile"
ON profiles FOR SELECT
USING (auth.uid() = id);
-- Policy: users can update own data
CREATE POLICY "Users update own profile"
ON profiles FOR UPDATE
USING (auth.uid() = id);
Queries
// Select
const { data } = await supabase
.from('profiles')
.select('*')
.eq('id', userId);
// Insert
await supabase.from('profiles').insert({ name, email });
// Update
await supabase.from('profiles').update({ name }).eq('id', userId);
// Delete
await supabase.from('profiles').delete().eq('id', userId);
Storage
// Upload
await supabase.storage.from('avatars').upload(path, file);
// Get URL
supabase.storage.from('avatars').getPublicUrl(path);
Realtime
supabase
.channel('messages')
.on('postgres_changes', { event: 'INSERT', table: 'messages' }, callback)
.subscribe();
Postgres Performance Best Practices
Critical priority: Query Performance
-- ALWAYS use indexes on filtered columns
CREATE INDEX idx_profiles_email ON profiles(email);
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_created_at ON orders(created_at);
-- Partial index for frequent queries
CREATE INDEX idx_active_users ON profiles(id) WHERE is_active = true;
-- Composite index for multi-column queries
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
-- ANALYZE slow queries
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 'xxx';
Critical priority: Connection Management
// USE Supabase's connection pooling (Supavisor)
// In Transaction mode for serverless
const supabase = createClient(url, key, {
db: { schema: 'public' },
auth: { persistSession: true },
});
// AVOID direct connections in serverless
// Always use the pooler (port 6543 instead of 5432)
High priority: Schema Design
-- Correct data types (no VARCHAR when UUID is enough)
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES profiles(id),
total_cents INTEGER NOT NULL, -- Not FLOAT for amounts
status TEXT NOT NULL DEFAULT 'pending',
metadata JSONB DEFAULT '{}', -- JSONB not JSON
created_at TIMESTAMPTZ DEFAULT now()
);
-- Avoid SELECT * in production
-- Specify the necessary columns
const { data } = await supabase
.from('orders')
.select('id, status, total_cents') -- NOT '*'
.eq('user_id', userId);
Medium priority: Security & RLS
-- Performant RLS: avoid subqueries in policies
-- GOOD: direct comparison
CREATE POLICY "own_data" ON orders
FOR ALL USING (user_id = auth.uid());
-- BAD: subquery in the policy (slow)
CREATE POLICY "team_data" ON orders
FOR ALL USING (
user_id IN (SELECT member_id FROM team_members WHERE team_id = current_setting('app.team_id'))
);
-- BETTER: use a JWT claim
CREATE POLICY "team_data" ON orders
FOR ALL USING (
team_id = (auth.jwt() -> 'app_metadata' ->> 'team_id')::uuid
);
Medium priority: Data Access Patterns
-- Cursor-based pagination (not OFFSET for large tables)
-- GOOD: cursor-based
const { data } = await supabase
.from('orders')
.select('*')
.gt('created_at', lastSeenDate)
.order('created_at', { ascending: true })
.limit(20);
-- BAD: offset-based (slow on large tables)
const { data } = await supabase
.from('orders')
.select('*')
.range(1000, 1020); // Scans 1020 rows
Monitoring
-- Slowest queries
SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
-- Tables without index used
SELECT relname, seq_scan, seq_tup_read
FROM pg_stat_user_tables
WHERE seq_scan > 100
ORDER BY seq_tup_read DESC;
-- Unused indexes
SELECT indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0;
When not to use it
- →When using a database other than Postgres
- →When not using Supabase for backend services
- →When the task does not involve authentication, database, or storage
Limitations
- →The skill does not cover all PostgreSQL features.
- →The skill does not provide UI components for Supabase interactions.
- →The skill does not manage Supabase project creation or infrastructure.
How it compares
This skill offers specific Supabase-focused code patterns and performance best practices, unlike general backend development which may not optimize for Supabase's features.
Compared to similar skills
dev-supabase side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| dev-supabase (this skill) | 0 | 2mo | Review | Intermediate |
| prisma-expert | 12 | 6mo | Review | Intermediate |
| convex-functions | 4 | 6mo | No flags | Intermediate |
| cloudbase-document-database-web-sdk | 1 | 2mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by aibot88
View all by aibot88 →You might also like
prisma-expert
davila7
Prisma ORM expert for schema design, migrations, query optimization, relations modeling, and database operations. Use PROACTIVELY for Prisma schema issues, migration problems, query performance, relation design, or database connection issues.
convex-functions
waynesutton
Writing queries, mutations, actions, and HTTP actions with proper argument validation, error handling, internal functions, and runtime considerations
cloudbase-document-database-web-sdk
TencentCloudBase
Use CloudBase document database Web SDK to query, create, update, and delete data. Supports complex queries, pagination, aggregation, and geolocation queries.
relational-database-web-cloudbase
TencentCloudBase
Use when building frontend Web apps that talk to CloudBase Relational Database via @cloudbase/js-sdk – provides the canonical init pattern so you can then use Supabase-style queries from the browser.
convex
waynesutton
Umbrella skill for all Convex development patterns. Routes to specific skills like convex-functions, convex-realtime, convex-agents, etc.
supabase-hello-world
jeremylongshore
Create a minimal working Supabase example. Use when starting a new Supabase integration, testing your setup, or learning basic Supabase API patterns. Trigger with phrases like "supabase hello world", "supabase example", "supabase quick start", "simple supabase code".