Home / Cursor rules for Next.js + Supabase
Cursor rules for Next.js + Supabase
Agents get the same few things wrong in a Next.js + Supabase app, and those mistakes are the expensive ones:
- Creating tables without row-level security, or switching RLS off "to fix the error".
- Trusting
getSession()on the server instead ofgetUser(), which re-validates the token. - Creating Supabase clients all over the place instead of one server helper and one browser helper with
@supabase/ssr. - Granting paid access from the Stripe success redirect instead of a verified webhook.
- Prefixing secrets with
NEXT_PUBLIC_, which ships them to every browser.
How Cursor rules work
Put .mdc files in .cursor/rules/. The front matter decides when a rule loads: alwaysApply: true for core rules, or globs so a rule loads only when matching files are in context. Keep each rule small and scoped. One giant rules file gets skimmed and ignored. For Codex, Claude Code and other tools, mirror the core rules in AGENTS.md.
A layout that works
00-core (always on), 20-supabase-auth (globs: lib/supabase/**, middleware.ts), 30-database-rls (supabase/**), 40-stripe (app/api/stripe/**), 50-env-secrets (.env*, lib/env.ts). The RLS rule below is the one that saves you the most money.
Free snippet: copy it
--- description: Migrations and row-level security globs: supabase/** alwaysApply: false --- - Each migration: create table + alter table ... enable row level security + policies, in one file. - Policies use (select auth.uid()) for performance; separate policies per command (select/insert/update/delete). - Add indexes on every column used in a policy or foreign key. - Never disable RLS to 'make it work'. If a query fails, fix the policy and explain it. - Regenerate types after schema changes: pnpm supabase gen types typescript --local > lib/database.types.ts
Want the whole drawer?
The Vibe Starter Rules Pack ($19) adds AGENTS.md, CLAUDE.md, 8 scoped rules (auth, Stripe webhooks, env, tests, UI), 12 slash-command prompts and launch checklists.
See the pack