AI coding rules · v1.0

Stack Pack: Cursor rules and hooks for Next.js, Drizzle, Better Auth, and Polar

Cursor rules, skills, and Claude Code hooks for one stack: Next.js 16 App Router, Drizzle ORM on Postgres, Better Auth, and Polar. The Better Auth Cursor rules cover config, sessions, cookies, and the organization plugin. The whole pack is designed to keep your AI agent on current APIs and away from this stack's common launch mistakes, and a launch-check script looks for those mistakes in your repo. This is a rules pack, not a boilerplate: you add it to your own app.

$15 (plus VAT where applicable). One-off. Single-user commercial licence.

Get the Stack Pack: $15 (plus VAT where applicable)

Sold via Gumroad · digital download

20 launch checks, run offline. Real terminals: the guard denies npx drizzle-kit push --force and cat .env.local; the broken example reports PL-VERIFY and PL-RAWBODY, '2 finding(s): 2 high', each with a fix; the good app has 0 findings. Both: 'can't prove the app is secure.'

What's inside

  • Instructions for your agents. AGENTS.md (read by Codex, the GitHub Copilot coding agent, and other AGENTS.md readers), CLAUDE.md for Claude Code, a generated .github/copilot-instructions.md, and 6 Cursor rules: project, Next.js 16, Drizzle, Better Auth, Polar, and security. A sync script keeps the copies in step with AGENTS.md.
  • 6 skills.
    • Add a Drizzle table with a committed migration and owner-scoped queries.
    • Protect a page, Server Action, or route with a Better Auth session check.
    • Polar checkout linked to the signed-in user, with access granted from webhooks.
    • Polar webhooks with signature checks, dedupe, and upserts.
    • Teams with roles (Better Auth organization plugin).
    • A launch check.
  • 3 Claude Code hooks.
    • A guard designed to deny drizzle-kit push --force, pushes or migrations aimed at a non-local database URL, direct psql to hosted databases, Vercel and Netlify production deploys, write calls to the production Polar API, reading .env files, real-looking Polar tokens and webhook secrets in code, database or server-auth imports in client components, and webhook routes that parse the body without a signature check.
    • A typecheck after each TypeScript edit.
    • A test gate before the agent finishes.
  • Launch check. node scripts/launch-check.mjs runs 20 checks on your repo offline, including Better Auth secret, base URL, trusted origins, CSRF/origin checks, cookie settings, and nextCookies() order; Server Actions that write without a session check; missing or gitignored Drizzle migrations, drizzle-kit push in build scripts, database imports in client code, and updates or deletes filtered by id only; Polar and Lemon Squeezy webhook signature checks, raw-body handling, and dedupe; and secrets exposed through NEXT_PUBLIC_, client code, or committed .env files. Each finding has a severity, file:line, and a fix.
  • Plugins. The skills and hooks as a Claude Code plugin, and the rules and skills as a Cursor plugin, each with a local marketplace file.
  • Reference wiring (fixtures/good-app). Better Auth with the Drizzle adapter, organization roles, and the Polar plugin; owner-scoped queries; and a Polar webhook route with verification, dedupe, and entitlement upserts. It's there to compare against, not to start from.
  • Already on Lemon Squeezy? A short, dated note on securing your current Lemon Squeezy webhook and on moving to Polar, with a pointer to Stripe's own docs if you'd rather use Stripe Managed Payments (this pack has no Stripe-specific rules or checks).

Who it's for

  • You're building, or about to launch, an app on Next.js 16 App Router, Drizzle on Postgres, Better Auth, and Polar.
  • You write code with Claude Code, Cursor, Codex, or the GitHub Copilot coding agent and want them working from rules written for this stack.
  • You want a pre-launch scan you can run offline and in CI (--json, --strict).

Who it isn't for

  • You want a starter app. This is a rules pack, not a boilerplate; the reference wiring is for comparison.
  • You bill with Stripe. The pack has no Stripe-specific rules or checks.
  • Your database isn't Postgres. The checks are for Postgres only.
  • You want the hooks in Cursor, Codex, or Copilot. The hooks are for Claude Code; the other tools get the rules and skills.

Building on a different stack? Ship-Ready AI Rules is our pack for Next.js apps on a different database and auth setup, with Stripe for payments, and the Ship It bundle puts AI Rules v2, Launch Audit, and Solo Founder OS Pro in one checkout.

Cursor rules for Drizzle, Better Auth, Next.js, and Polar

Six rule files in .cursor/rules/. Two always apply (project and security), and the other four attach by file path. Some of what they tell the agent:

  • Drizzle (20-drizzle.mdc). Designed to have your agent change the schema, run drizzle-kit generate, and commit the SQL and drizzle/meta/. It tells the agent to use drizzle-kit push only on a throwaway local database and never with --force, to include the owner or org in every select, update, or delete on user data, and to import db only on the server.
  • Better Auth (30-better-auth.mdc). Tells your agent to read the secret and base URL from env and fail fast if either is missing, use the Drizzle adapter with provider: "pg", build trusted origins from env with no bare "*", and keep nextCookies() last. It instructs the agent to check sessions on the server with auth.api.getSession and organization permissions with auth.api.hasPermission.
  • Next.js 16 (10-nextjs.mdc). Reminds your agent that params and searchParams are Promises, and that every Server Action is a public POST endpoint, so each action should check the user first. It tells the agent to keep proxy.ts to optimistic redirects and never match /api/auth or webhook paths.
  • Polar (40-polar.mdc). Tells your agent to configure the Better Auth Polar plugin so the Polar customer's external_id is your user id, verify webhooks on the raw body, dedupe on webhook-id, and grant access from the entitlement row, never from the checkout success redirect.

See it run

Output from the pack's own runs, copied as captured. "…" marks lines we left out.

The guard denying a forced push and a .env read

$ npx drizzle-kit push --force
{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"[stack-pack guard] Blocked: `drizzle-kit push --force` auto-approves data-loss statements. Generate a migration (`drizzle-kit generate`) and let the user review it."}}  [exit 0]
$ cat .env.local
{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"[stack-pack guard] Blocked: this command would read, print or copy a secret .env file. Use .env.example instead."}}  [exit 0]

Hook and launch-check tests

…
> stack-pack-nextjs-drizzle-betterauth-polar@1.0.1 test:hooks
> node --test tests/hooks.test.mjs tests/guard-probes.test.mjs
…
ℹ tests 198
ℹ suites 0
ℹ pass 198
ℹ fail 0
…
> stack-pack-nextjs-drizzle-betterauth-polar@1.0.1 test:checks
> node --test tests/checks.test.mjs
…
ℹ tests 32
ℹ suites 0
ℹ pass 32
ℹ fail 0
…
[exit 0]

How it works

  1. Install. Copy everything in pack/ into your repo root, including the dot-folders. If you already have .claude/settings.json, merge it by hand. Or install the Claude Code plugin:
    /plugin marketplace add ./path/to/plugin
    /plugin install stack-pack@stack-pack-local
    For Cursor, copy plugin/stack-pack-cursor to ~/.cursor/plugins/local/stack-pack, reload the window, and copy pack/AGENTS.md and pack/scripts/ into your repo.
  2. List env names, not values. .env.example holds the names (DATABASE_URL, BETTER_AUTH_SECRET, POLAR_ACCESS_TOKEN, and the rest); real values stay in .env.local.
  3. Run the launch check.
    node scripts/launch-check.mjs
    Fix HIGH findings first. --strict fails on MEDIUM too, and --json gives machine output for CI.
  4. Work as usual. In Claude Code, ask for "a projects table owned by the user" and the add-drizzle-table skill loads. In Cursor, the rules attach by file path.
  5. Keep agents in sync. After you edit AGENTS.md, run node scripts/sync-agents.mjs (add --check in CI).

How we tested it

  • 247 automated tests pass on Node 24.22, none skipped: 198 hook tests (including 158 adversarial probes: one for each of the 109 from our 1.0.0 QA review plus 49 added in 1.0.1, fail-closed cases, and 1 MB inputs), 32 launch-check tests (each check fires on its broken example, and the reference wiring has zero findings), 11 sync-script tests, and 6 reference-wiring tests. Those 6 apply the committed Drizzle migration in PGlite (Postgres in WASM), check that one user can't change another user's rows, and verify Polar webhook signatures with the official @polar-sh/sdk.
  • The reference wiring type-checks and builds with next build on Next.js 16.4.2.
  • The Claude Code plugin passes claude plugin validate --strict; the Cursor plugin passes Cursor's own plugin validator.
  • Written against next 16.4.2, drizzle-orm 0.45.4, drizzle-kit 0.31.11, better-auth 1.7.12, and @polar-sh/sdk 1.0.2 (checked 23 Oct 2026).

What this doesn't do

  • The guard reads commands, not your environment. A push whose database URL comes from .env isn't detected, and neither are aliases or functions, scripts in files (sh deploy.sh, make) or commands built at run time; the docs list the limits.
  • The launch check is pattern matching, so it can miss issues. A clean run doesn't mean an app is secure.
  • Not tested in a live Claude Code or Cursor session, against a live Polar account or against a hosted database, or running the reference wiring as a server.
  • The hooks are for Claude Code. Cursor, Codex, and Copilot get the rules and skills.
  • The checks are for Postgres only, and there are no Stripe-specific rules or checks.

Requirements

Needs Node 24 or later. As of 23 Oct 2026, @polar-sh/better-auth 2.1.0 and @polar-sh/nextjs 1.1.0 declare Node 24+ (the Better Auth CLI, npx auth@latest, declares Node 22.12+), so the reference app and any app on this stack need Node 24+. The pack's own rules, hooks and scripts have no dependencies; its full test run passed on Node 24.22. The guard is designed to fail closed (deny the action) if it crashes or times out, on Claude Code 2.1.295 or later. On earlier versions, a hook that times out or can't start lets the action run (as of 23 Oct 2026, Claude Code's npm stable and latest channels are 2.1.308 and 2.1.309). The checks are for Postgres only.

FAQ

Is this a starter app?
No. It's a rules pack: rules, skills, hooks, and a launch-check script that you add to your own app. fixtures/good-app is reference wiring that the checks and tests run against, not a starter kit.
Which AI coding tools does it work with?
Claude Code reads CLAUDE.md and gets the skills and the 3 hooks. Cursor gets 6 rules and the skills, as copy-in files or a Cursor plugin. Codex and the GitHub Copilot coding agent read AGENTS.md, and a generated .github/copilot-instructions.md is included. The hooks are for Claude Code only.
Which Node version do I need?
Node 24 or later. As of 23 Oct 2026, @polar-sh/better-auth 2.1.0 and @polar-sh/nextjs 1.1.0 declare Node 24+, so any app on this stack needs Node 24+. The pack's own hooks and scripts have no dependencies.
Will the guard stop every push to my production database?
No. It's designed to deny drizzle-kit push --force and pushes or migrations aimed at a non-local database URL on the command line. It reads commands, not your environment, so a plain push whose database URL comes from .env isn't detected. The rules also tell the agent not to push to shared databases, and the launch check flags drizzle-kit push in build scripts.
If the launch check comes back clean, is my app secure?
Not necessarily. It runs 20 pattern checks offline, so it can miss issues. A clean run doesn't mean an app is secure. Treat it as a pre-launch list, not an audit.
Has it been tested against a live Polar account?
No. It hasn't been tested in a live Claude Code or Cursor session, against a live Polar account or a hosted database, or with the reference wiring running as a server. Polar webhook signatures are checked in tests with the official @polar-sh/sdk.
Does it cover the Better Auth Polar plugin and Polar webhooks?
Yes, as two separate pieces. The Polar Cursor rule and the polar-checkout-access skill are designed to have your agent set up the Better Auth Polar plugin (@polar-sh/better-auth) for checkout and the customer portal, with createCustomerOnSignUp so the Polar customer's external_id is your user id. For webhooks, they point the agent to a separate route, app/api/webhooks/polar/route.ts, rather than the Better Auth plugin. The polar-webhooks skill is designed to have your agent read the raw body and verify it with validateEvent from @polar-sh/sdk, or with the Webhooks() adapter from @polar-sh/nextjs. It also tells the agent to return 403 on a bad signature, dedupe on webhook-id, and upsert access rows. The pack doesn't cover configuring webhooks through the Better Auth plugin itself.
Do I get updates, and what about refunds?
Free updates within 1.x: any 1.x updates we release are free for existing buyers, downloadable from your Gumroad library. Updates come when we choose to release them; there's no set schedule and no promise of particular future features. Digital download: by buying, you ask for immediate access and agree that your 14-day right to cancel ends once the download or access starts. Our voluntary 14-day "if it didn't help" refund guarantee still applies, and your rights for faulty content are not affected.

Get the Stack Pack: $15 (plus VAT where applicable)

Claude and Claude Code are trademarks of Anthropic. Cursor is a trademark of Anysphere, Inc. Postgres and PostgreSQL are registered trademarks of the PostgreSQL Community Association of Canada. Polar, Better Auth, Drizzle, Next.js, Vercel, Netlify, Lemon Squeezy, Stripe, GitHub, GitHub Copilot, Microsoft, OpenAI, Codex, Google, Gemini, PGlite, Node.js and other product names belong to their respective owners. They are used here only to identify the tools this pack works with. This pack is not affiliated with, sponsored by or endorsed by any of them.