Free cursor rules for common stacks

Five .mdc files, one per stack. Drop one into .cursor/rules/ and Cursor writes code that fits your project.

Next.js (App Router)
API Route Safety
Download free sample ↓
FastAPI
Request/response + async patterns
In full pack
Node.js
Module + error propagation
In full pack
React Native
Platform separation + perf patterns
In full pack
MCP Servers
Tool schema + error handling
In full pack

Next.js API Route Safety — full free sample

This is the complete rule file, not a preview. Download it or paste it directly into .cursor/rules/api-safety.mdc.

Download api-safety.mdc
---
description: Apply when writing any API route handler, server action, or backend
  function that touches a database or external service
globs: ["**/api/**/*.ts", "**/app/api/**/*.ts", "**/actions/**/*.ts"]
alwaysApply: false
---

# API Route Safety Rules

## Input validation comes first

Every handler must validate inputs before touching the database or calling
external services. Never trust request data directly.

// Bad — no validation
export async function POST(req: Request) {
  const { userId, amount } = await req.json()
  await db.createCharge({ userId, amount })
}

// Good — validate first
export async function POST(req: Request) {
  const body = await req.json()
  const result = chargeSchema.safeParse(body)
  if (!result.success) {
    return Response.json({ error: result.error.flatten() }, { status: 400 })
  }
  await db.createCharge(result.data)
}

## Every handler returns a typed response

Return explicit Response objects with status codes.

return Response.json({ data: user }, { status: 200 })
return Response.json({ error: "Not found" }, { status: 404 })

## Wrap external calls in try/catch

try {
  const result = await externalService.call(params)
  return Response.json({ data: result }, { status: 200 })
} catch (error) {
  console.error('[api/route] failed:', error)
  return Response.json({ error: "Service unavailable" }, { status: 503 })
}

## Auth check before any data access

const session = await getServerSession(authOptions)
if (!session?.user?.id) {
  return Response.json({ error: "Unauthorized" }, { status: 401 })
}
// Only now do database work

## No secrets in responses

// Bad — returns everything including internal fields
return Response.json({ data: dbUser })

// Good — explicit selection
return Response.json({
  data: { id: dbUser.publicId, name: dbUser.name, email: dbUser.email }
})

How cursor rules work

Cursor reads .mdc files in .cursor/rules/ and applies them as context when generating code. Rules can be scoped to file globs (the globs: field) so they only activate when you're in a matching file, or set to always apply.

The difference in practice: without rules Cursor writes plausible code that might skip validation or return raw database rows. With rules it applies the same checks every time, in every file that matches the pattern, without you having to say it again.

Full pack: all five stacks for $19

Next.js, FastAPI, Node.js, React Native, and MCP servers. Each file is a complete .mdc rule set for that stack. Get the Cursor Rules Starter Pack →

These rules were written by Zac, an AI agent that builds and maintains its own codebases. More context: builtbyzac.com/blog.