Vibemast guide: Cursor rules for Next.js and Supabase

Cursor rules for Next.js and Supabase: a working setup

If you build a Next.js and Supabase app with Cursor, the agent tends to repeat the same few mistakes. It creates tables without row-level security. It checks the session with the wrong call on the server. It reaches for a package that has been deprecated, or a file name from an older Next.js version. Project rules fix this by putting your conventions in front of the agent on every request. This guide shows how Cursor loads rules, a file layout that works, and three rules you can copy.

Checked on 27 Oct 2026 against Cursor's rules docs, the Next.js 16 docs and Supabase's server-side auth and Row Level Security docs. Next.js 16.4 is the current release; 15.5 still gets backports.

How Cursor loads rules

Project rules are .mdc files in .cursor/rules/. Cursor's docs are clear on two details that trip people up: the extension must be .mdc, and a plain .md file in that folder is ignored. Each file starts with frontmatter that decides when it loads.

Frontmatter Behaviour
alwaysApply: true Included in every chat
globs set, alwaysApply: false Attached when a matching file is in context
description only The agent reads the description and decides whether to pull the rule in
None of those Only used when you @-mention the rule

Cursor's own guidance is to keep each rule under 500 lines, split large rules into smaller ones, and avoid vague advice. Rules cost context on every request, so the always-on files should be short.

A layout that works

.cursor/rules/
  00-core.mdc            always on: stack, commands, how to work
  10-supabase-auth.mdc   attached to lib/supabase/**, proxy.ts, actions
  20-database-rls.mdc    attached to supabase/**
AGENTS.md                the same core rules for other tools

Keep the always-on file small and move anything that only matters for one part of the code into a glob-scoped rule. The agent then sees Supabase guidance when it touches Supabase files and not when it is styling a button.

Rule 1: core conventions (always on)

---
description: Core conventions for Next.js App Router + Supabase
alwaysApply: true
---
- Check package.json for the installed next version before using an API.
- Default to Server Components. Add "use client" only to the smallest
  component that needs state, effects or browser APIs.
- Mutations go through Server Actions or Route Handlers. Validate every
  input with a schema (Zod) on the server.
- params, searchParams, cookies() and headers() are async: await them.
- Anything prefixed NEXT_PUBLIC_ is public. Secrets never go there.
- You are not done until typecheck, lint and build have run and you
  have read the output.

The async line is real. Next.js 15 made these request APIs asynchronous with a temporary compatibility layer, and Next.js 16 removed synchronous access entirely, so old tutorial code fails on current versions.

Rule 2: Supabase auth on the server

---
description: Supabase clients and auth checks
globs: lib/supabase/**,proxy.ts,middleware.ts,app/**/actions.ts
alwaysApply: false
---
- Use @supabase/ssr: createBrowserClient in the browser,
  createServerClient on the server, one factory per file in lib/supabase/.
- Cookie handling must implement getAll and setAll.
- On the server, identify the user with supabase.auth.getClaims().
  Never trust supabase.auth.getSession() alone on the server.
- Use the publishable key in the browser. The secret key stays in
  server-only code and is never in a NEXT_PUBLIC_ variable.

Supabase's docs say the same thing about getSession(): it reads the session from the cookie without revalidating it, and anyone can forge a cookie. getClaims() verifies the token's signature on each call. Use getUser() when you need an up-to-date user record from the Auth server.

Rule 3: Row Level Security

---
description: Migrations and Row Level Security
globs: supabase/**
alwaysApply: false
---
- Every table in an exposed schema gets RLS enabled, with explicit
  policies, in the same migration that creates it.
- One policy per operation (select, insert, update, delete), each with
  a "to" clause naming the role.
- Wrap helpers in a select: (select auth.uid()) = user_id.
- Update policies need both "using" and "with check".
- Never authorise from user_metadata. Users can edit it.
- Never disable RLS to make a query work. Fix the policy.

These lines come straight from the habits in Supabase's own guide: separate policies per operation, name the role with to, wrap auth.uid() in a select so Postgres can cache it, and keep authorisation data in app_metadata rather than user_metadata. For a fuller checklist, see our Supabase RLS checklist for AI-built apps.

Version traps worth writing down

  • middleware.ts became proxy.ts in Next.js 16. The function is named proxy and runs on the Node.js runtime. Supabase's docs warn that on Next.js 15 and earlier a proxy.ts file is never called, so sessions never refresh and users get signed out. Tell the agent which one your version uses.
  • next lint is removed in Next.js 16. Run ESLint directly.
  • Turbopack is the default bundler in Next.js 16. A custom webpack config makes next build fail unless you opt out.

Rules go stale. When the agent makes the same mistake twice, add a line. When you upgrade a major version, ask the agent to check the rules against the release notes.

Keep the files in sync

Cursor also reads AGENTS.md in the project root and in subfolders, which is useful if you switch tools. The cost is that you now maintain more than one file. The Vibemast Ship-It Kit handles that with a generator script: the rules are written once, and the script writes the Cursor rules, AGENTS.md, CLAUDE.md and Copilot instructions. It includes a full Next.js and Supabase rule set with the version traps above, plus 25 build prompts, 8 rescue prompts and a 20-point security audit. If you want to try the approach on one stack first, the free mini pack has the generator and a Vite and React rule set.

Before you ship a Next.js and Supabase app

Rules stop the agent writing unsafe code, but they do not check code that already exists. Before launch:

  1. Run the Supabase RLS checklist for AI-built apps on every table.
  2. Work through the Pre-launch security checklist for vibe-coded apps, especially secrets in NEXT_PUBLIC_ variables and payment webhooks.
  3. Keep the same rules in AGENTS.md and CLAUDE.md if anyone on the project uses Claude Code. See the Cursor rules vs CLAUDE.md vs AGENTS.md comparison.

The Ship-It Kit has the full Next.js and Supabase rule set (Cursor, Claude Code, Copilot and AGENTS.md versions, ready to copy) and 20 audit prompts that walk an agent through these checks one area at a time.

Who the paid kit is for, and who it is not for

  • Worth it if you build on one of its four stacks (Next.js with Supabase, Vite with React, FastAPI, Phaser) and want tested files and prompts today instead of writing and testing your own.
  • Not worth it if you only need one rules file for one project. The free guides and the free mini pack are enough, and you can adapt them yourself.

Related guides

FAQ

Where do Cursor rules go?

In .cursor/rules/ at the project root, as .mdc files. A .md file in that folder is ignored.

Should I use .cursorrules or .cursor/rules?

Use .cursor/rules. Cursor's current docs describe project rules in that folder and AGENTS.md as the simpler alternative. Older projects may still have a .cursorrules file; moving its content into rule files lets you scope it.

Why does Cursor ignore my rules?

Check the rule type first. A rule with alwaysApply: false and no description or globs only loads when you @-mention it. Also check the extension and the glob. If everything is set correctly, shorten the file: very long always-on rules compete with your prompt for attention.

Do rules replace Row Level Security?

No. Rules only make the agent more likely to write correct policies. Test them yourself with two accounts, or with supabase test db.

Back to blog

Skip the setup: get the Ship-It Kit

Agent rules for 4 stacks, a generator for AGENTS.md, CLAUDE.md and Cursor rules, 25 build prompts, 8 rescue prompts and 20 security audit prompts.

Launch price US$17 Regular price US$22

Get the Ship-It Kit

Prices in US dollars. Your bank converts at checkout.Made in New Zealand by Vibemast.

Launch price for early buyers. Instant download. One-time payment. Not working? Fixed or refunded within 14 days.

For business owners

Run a business, not just code?

Our free Business Brain setup prompt makes ChatGPT, Claude or Gemini know your business, so replies, quotes and posts sound like you. It takes about 10 minutes and needs no technical skills. Handy for your own business, or for clients who keep asking how to use AI.