← Blog

Best Cursor rules for a Next.js SaaS (copy-paste .mdc files)

By VibeBoot ·

Cursor is only as consistent as the context you give it. Without rules, every new chat re-decides where files go, which auth helper to call and whether to create a new database client. Project rules fix that. This guide explains how Cursor rules work today and gives you a set of rules for a Next.js SaaS (App Router, Auth.js, Prisma, Stripe) that you can copy and adapt.

How Cursor rules work

Rules live in .cursor/rules/ as .mdc files: Markdown with a small frontmatter block.

---
description: Rules for anything touching billing
globs: src/app/api/stripe/**,src/lib/stripe.ts
alwaysApply: false
---
# Stripe rules
- ...

Other agents don't read .cursor/rules, so also keep an AGENTS.md (read by many coding agents) and, if you use Claude Code, a CLAUDE.md with the same essentials.

What makes a rule good

Rule 1: project.mdc (always on)

---
description: Project stack, structure and conventions
alwaysApply: true
---
# Project rules

## Stack
- Next.js App Router (src/ dir), React Server Components by default, TypeScript strict, Tailwind CSS v4.
- Auth.js v5 with Prisma adapter. Stripe for subscriptions. Prisma ORM.

## File structure
- src/app/ routes; API routes in src/app/api/**/route.ts.
- src/auth.ts: import auth, signIn, signOut from "@/auth".
- src/lib/db.ts: Prisma singleton `db`. Never instantiate PrismaClient elsewhere.
- src/components/: shared UI.

## Conventions
- Prefer Server Components and Server Actions; "use client" only for interactivity.
- Protect pages server-side: const session = await auth(); if (!session?.user?.id) redirect("/login").
- Always scope DB queries to the signed-in user.
- Only NEXT_PUBLIC_* env vars may reach the browser. Add every new env var to .env.example.
- Validate user input on the server before writing to the DB.

## Verify
- npm run lint and npm run build must pass before you finish.

## Do not
- Do not swap libraries (auth, ORM, payments) without being asked.
- Do not commit .env files or real keys.

The "Do not swap libraries" line is worth its weight: without it, an agent fixing an auth bug may decide to migrate you to a different auth library.

Rule 2: stripe.mdc (billing files only)

---
description: Rules for billing, Stripe and subscriptions
globs: src/app/api/stripe/**,src/lib/stripe.ts,src/app/pricing/**
alwaysApply: false
---
# Stripe rules
- Use getStripe() from "@/lib/stripe"; never create a Stripe client at module top level.
- Webhook must read the raw body with await req.text() and verify with stripe.webhooks.constructEvent.
- Handle new events with a new case in the webhook route; keep handlers idempotent.
- Stripe is the source of truth: update subscription fields only from the webhook.
- Redirect URLs use NEXT_PUBLIC_APP_URL.

Each line here prevents a common agent mistake. For the full billing setup, see How to add Stripe subscriptions to a Next.js app with Cursor.

Rule 3: database.mdc (schema and db files only)

---
description: Rules for Prisma schema and database access
globs: prisma/**,src/lib/db.ts
alwaysApply: false
---
# Database rules
- Only import the client as import { db } from "@/lib/db".
- Keep Auth.js models (User, Account, Session, VerificationToken) compatible with @auth/prisma-adapter.
- New models: id String @id @default(cuid()), createdAt, updatedAt @updatedAt, and a userId relation with onDelete: Cascade.
- On SQLite, avoid enums, scalar lists and @db.* types.
- After schema changes run npx prisma db push (dev) or prisma migrate dev on Postgres.

Add a "how to add a feature" recipe

The single most useful section in a project rule is a recipe the agent can follow for any feature:

  1. Model: add it to prisma/schema.prisma, related to User with onDelete: Cascade, then push the schema.
  2. Data access: query with db inside Server Components or Server Actions.
  3. UI: src/app/<route>/page.tsx; reusable pieces in src/components/.
  4. Mutations: Server Actions plus revalidatePath(); route handlers only for webhooks.
  5. Auth/billing: check auth() first, then the subscription status for paid features.
  6. Verify: lint and build.

With this in place, a prompt like "Add a Projects feature: users can create, rename and delete projects. Free users get 1 project, Pro unlimited." produces code that lands in the right files on the first try far more often.

Keep rules alive

Skip the setup

The VibeBoot SaaS Starter ships with these three rule files plus AGENTS.md and CLAUDE.md, already matched to a working Next.js 16 + Auth.js + Prisma + Stripe codebase.