

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# Supabase Full-Stack Development — Cursor Rules23You are an expert full-stack developer building applications with Supabase as the backend, including database, auth, storage, edge functions, and real-time subscriptions.45## Code Style67- Use TypeScript throughout. Generate types from Supabase with `supabase gen types typescript`.8- Never use `any` when working with Supabase queries — use the generated `Database` type.9- Type your Supabase client: `const supabase = createClient<Database>(url, key)`.10- Use `camelCase` for application code, `snake_case` for database column and table names.11- Keep database queries in a data access layer (repository or service module), not in UI components.12- Use the Supabase client libraries, not raw HTTP calls to the REST API.1314## Database Design1516- Use PostgreSQL best practices. Supabase is PostgreSQL — leverage its full power.17- Use `uuid` primary keys generated with `gen_random_uuid()` for all tables.18- Include `created_at` (with default `now()`) and `updated_at` timestamps on every table.19- Use foreign key constraints for all relationships. Define `ON DELETE` behavior explicitly (CASCADE, SET NULL, RESTRICT).20- Use `text` over `varchar` in PostgreSQL (no performance difference, simpler). Add `CHECK` constraints for length limits.21- Use database enums for columns with fixed allowed values.22- Add indexes on columns used in WHERE, JOIN, and ORDER BY clauses.23- Use composite indexes for queries that filter on multiple columns.24- Name constraints and indexes explicitly: `idx_users_email`, `fk_posts_user_id`, `chk_users_email_format`.2526## Row-Level Security (RLS)2728- ALWAYS enable RLS on every table. No exceptions. Tables without RLS are publicly accessible.29- Write policies for every operation: SELECT, INSERT, UPDATE, DELETE. Be explicit about who can do what.30- Use `auth.uid()` to reference the current user in policies:31```sql32 CREATE POLICY "Users can read own data" ON users33 FOR SELECT USING (auth.uid() = id);34```35- Use `auth.jwt()` for claims-based access: `(auth.jwt() ->> 'role')::text = 'admin'`.36- Test RLS policies with different user roles. Use Supabase's policy testing tools.37- For public tables (e.g., published posts), create an explicit SELECT policy: `USING (published = true)`.38- Service role key bypasses RLS — never use it in client-side code.39- Use security definer functions for operations that need elevated privileges.4041## Authentication4243- Use Supabase Auth for all authentication. Do not build custom auth.44- Support multiple auth providers as needed: email/password, OAuth (Google, GitHub), magic link.45- Use `supabase.auth.getSession()` to check auth state. Use `supabase.auth.onAuthStateChange()` for reactive auth.46- Store user metadata in a separate `profiles` table linked to `auth.users` with a trigger:47```sql48 CREATE FUNCTION handle_new_user()49 RETURNS trigger AS $$50 BEGIN51 INSERT INTO public.profiles (id, email, full_name)52 VALUES (NEW.id, NEW.email, NEW.raw_user_meta_data ->> 'full_name');53 RETURN NEW;54 END;55 $$ LANGUAGE plpgsql SECURITY DEFINER;56```57- Implement proper sign-out: `await supabase.auth.signOut()`. Clear any local state.58- Use `supabase.auth.getUser()` for server-side verification (validates JWT with Supabase).59- Use `getSession()` for client-side checks only (session is from local storage, not verified).6061## Querying Data6263- Use the Supabase query builder for type-safe queries:64```typescript65 const { data, error } = await supabase66 .from('posts')67 .select('id, title, author:profiles(name, avatar_url)')68 .eq('published', true)69 .order('created_at', { ascending: false })70 .range(0, 9)71```72- Always handle errors: `if (error) { throw new Error(error.message) }`.73- Use `.select()` with specific columns instead of `*` to minimize data transfer.74- Use foreign table joins in `.select()` for related data: `'*, author:profiles(*)'`.75- Use `.range(from, to)` for pagination. Use `.limit()` for limiting results.76- Use `.single()` when expecting exactly one row (throws error if 0 or 2+ rows).77- Use `.maybeSingle()` when expecting 0 or 1 rows.78- Use RPC for complex queries: `supabase.rpc('function_name', { param: value })`.7980## Edge Functions8182- Write Edge Functions in TypeScript using Deno runtime.83- Use Edge Functions for: webhooks, third-party API integrations, complex server logic, scheduled tasks.84- Validate all input at the top of the function.85- Use the Supabase client with the service role key inside Edge Functions for admin operations.86- Set appropriate CORS headers for functions called from the browser.87- Handle errors and return consistent JSON responses with appropriate status codes.88- Use `Deno.env.get()` for accessing secrets and environment variables.89- Keep Edge Functions focused — one function per responsibility.9091## Real-Time9293- Use Supabase Realtime for live updates: database changes, presence, broadcast.94- Subscribe to database changes with channel subscriptions:95```typescript96 supabase.channel('posts')97 .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'posts' }, handleInsert)98 .subscribe()99```100- Use filters in subscriptions to limit the data received: `filter: 'user_id=eq.${userId}'`.101- Unsubscribe from channels when the component unmounts to prevent memory leaks.102- Use Presence for tracking online users: `channel.track({ user_id, online_at })`.103- Use Broadcast for ephemeral messages that don't need database persistence (typing indicators, cursor positions).104- Handle reconnection gracefully. Supabase client reconnects automatically, but re-subscribe to channels after reconnect.105106## Storage107108- Use Supabase Storage for file uploads (images, documents, media).109- Create storage buckets with appropriate policies:110```sql111 CREATE POLICY "Users can upload to own folder" ON storage.objects112 FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);113```114- Use signed URLs for private files. Use public URLs for publicly accessible assets.115- Validate file type and size on both client and server before upload.116- Organize files by user or entity: `avatars/{user_id}/photo.jpg`, `posts/{post_id}/cover.png`.117- Use image transformations for responsive images: `supabase.storage.from('bucket').getPublicUrl('path', { transform: { width: 200 } })`.118119## Migrations120121- Use Supabase CLI migrations for all schema changes: `supabase migration new migration_name`.122- Write both up and down migrations.123- Never modify a migration that has been applied to production. Create a new migration instead.124- Include RLS policies in migrations, not as ad-hoc SQL.125- Use seed files (`supabase/seed.sql`) for development test data.126- Test migrations locally with `supabase db reset` before deploying.127128## Testing129130- Use the local Supabase development environment (`supabase start`) for testing.131- Test RLS policies by creating test users and verifying access patterns.132- Test Edge Functions with `supabase functions serve` and HTTP client tests.133- Write integration tests that exercise the full stack: client -> RLS -> database.134- Use database transactions for test isolation when possible.135- Mock the Supabase client in unit tests for service logic.136137## File Structure138139```140src/141 lib/142 supabase/143 client.ts — Supabase client initialization144 types.ts — Generated Database types145 middleware.ts — Auth middleware / session handling146 services/147 auth.ts — Auth helper functions148 posts.ts — Post data access functions149 storage.ts — Storage upload/download helpers150 hooks/ — React/Svelte hooks for Supabase151 useAuth.ts152 usePosts.ts153 useRealtime.ts154supabase/155 config.toml — Supabase project configuration156 migrations/ — Database migrations157 001_create_profiles.sql158 002_create_posts.sql159 functions/ — Edge Functions160 send-email/161 index.ts162 process-webhook/163 index.ts164 seed.sql — Development seed data165```166167## Security168169- NEVER expose the service role key in client-side code. Use it only in server-side contexts (Edge Functions, server-side rendering).170- Use the `anon` key in client-side applications. It respects RLS policies.171- Enable RLS on ALL tables. Audit tables without RLS regularly.172- Validate and sanitize all user input before database operations.173- Use parameterized queries (Supabase client handles this). Never concatenate user input into SQL.174- Implement rate limiting on Edge Functions that are publicly accessible.175- Audit RLS policies when modifying table structures — new columns may need policy updates.176- Use `security definer` functions cautiously. They run with the function owner's permissions.177178## Performance179180- Use database indexes for frequently queried columns.181- Use `.select()` with specific columns to reduce payload size.182- Implement pagination for list endpoints — never return unbounded result sets.183- Use database functions (RPC) for complex aggregations instead of multiple client queries.184- Cache Supabase auth sessions client-side (the Supabase client does this automatically).185- Use connection pooling (Supabase uses PgBouncer). Prefer `transaction` mode for serverless.186- Optimize real-time subscriptions: subscribe only to the data you need, use filters.187
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| survivorforge/cursor-rulesrules/ai-ml-python/.cursorrules · 16 | .cursorrules | teststylearchdeployment+2 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/langchain-ai/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+4 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/aws-serverless/.cursorrules · 16 | .cursorrules | teststylearchtypes+6 | 73/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/tailwindcss/.cursorrules · 16 | .cursorrules | lint-formatstylearchui+3 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/mern-stack/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/api-design-rest/.cursorrules · 16 | .cursorrules | lint-formatstylesecurityapi+3 | 69/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/api-microservices/.cursorrules · 16 | .cursorrules | buildteststylearch+5 | 92/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/chrome-extension/.cursorrules · 16 | .cursorrules | teststylearchtesting-strategy+4 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/clean-code/.cursorrules · 16 | .cursorrules | styledo-notagent-behaviourdocs | 57/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/database-sql/.cursorrules · 16 | .cursorrules | styletypessecuritydatabase+3 | 65/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-docker/.cursorrules · 16 | .cursorrules | setupbuildteststyle+4 | 93/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-infrastructure/.cursorrules · 16 | .cursorrules | buildteststylesecurity+3 | 93/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/django-rest/.cursorrules · 16 | .cursorrules | buildteststylearch+5 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/docker-devops/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 85/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/flutter-dart/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 89/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/fullstack-nextjs-prisma/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 96/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/go-gin/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+5 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/mobile-react-native/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 89/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-14-app-router/.cursorrules · 16 | .cursorrules | teststyletypestesting-strategy+3 | 71/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-app-router/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 81/100 | 13 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/survivorforge-cursor-rules-rules-supabase-fullstack-cursorrules)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.