May 29, 2025

Master Cursor Custom Rules to Align Gen AI with Your Code

Use Cursor’s Custom Rules to enforce coding standards, project structure, and test coverage. Make AI generate code that follows your team’s best practices.

Author

Ajinkya Vinayak PalaskarAjinkya Vinayak PalaskarSoftware Engineer III
Master Cursor Custom Rules to Align Gen AI with Your Code

Generative AI tools like Cursor are changing the way developers write code;, but let’s be honest, the default AI behaviour doesn’t always match how you or your team builds software. Whether it’s naming conventions, project structure, or the way you wire up API calls, out-of-the-box AI can feel like working with a junior dev who doesn’t quite get the vibe yet.

That’s where Cursor’s Custom Rules come in. Instead of adapting your codebase to fit AI’s suggestions, you can flip the script and make AI generate code that follows your standards, your structure, and your expectations.

In this blog, we’ll dive into what Cursor’s rules are, how they work, and how you can use them to bring structure, consistency, and actual team alignment to your AI-powered workflow. Just real, dev-focused examples that help you go from “AI that kind of helps” to “AI that codes like your best junior dev (who doesn’t forget lint rules).”

Understanding Cursor’s Custom Rules

At its core, Cursor’s Custom Rules feature gives developers a way to shape the behaviour of the AI assistant so it actually respects your coding preferences. It’s not just about giving it tips, it’s about creating structured, repeatable rules that get applied every time you prompt it in certain files or folders.

Cursor supports two types of rules:

  1. Project Rules: These are workspace-wide rules stored in .cursor/rules/ and committed to version control. They apply to everyone working in the repo, super useful for enforcing team-wide patterns, boilerplate structures, or naming conventions.
  2. User Rules: These live locally and are scoped only to your Cursor environment. Think of them as your personal tweaks or power-ups for one-off or experimental cases. Cursor stores them in your user settings directory.

To sum it up: Project rules = team alignment. User rules = personal productivity boosts.

How Do These Rules Actually Work?

Cursor rules work by defining:

  • File matchers (globs): Decide which files the rule applies to.
  • Prompts/Instructions: Tell Cursor what to do when editing those files.
  • Referenced files (optional): Provide extra context, like shared types, utility functions, or templates.

So instead of writing the same prompt over and over again, like "Please generate a Zod schema and name everything in camelCase", you just write the rule once, and Cursor applies it automatically in the right places.

What About .cursorrules?

If you’ve used Cursor in the past, you might’ve seen the old .cursorrules file in the root of your project. That format is now deprecated in favour of the new .cursor/rules/*.json system, which is much more flexible and easier to manage across teams.

Setting Up Custom Rules in Cursor

Now that we know what rules are and why they matter, let’s get into how to actually set them up. The cursor makes this surprisingly smooth. You don’t need any weird config voodoo, just a well-structured JSON file, a clear prompt, and you’re good to go.

The easiest way to get started is to use the built-in command:

Cmd + Shift + P → "New Cursor Rule"

This will prompt you for a name for the rule and create a markdown file at this location:

.cursor/rules/your-new-rule.mdc

Here’s what a full rule looks like:

---
description: Enforce Zod schemas in service layer
globs: ["src/services/**/*.ts"]
alwaysApply: true
referencedFiles: ["src/lib/validators.ts"]
---

When working in service files, always use Zod to validate inputs and outputs.
Follow the existing pattern from `validators.ts`.
Don't skip validation unless explicitly told to.

Let’s break this down:

  • description: Short explanation of what the rule does
  • globs: File patterns where the rule should apply (e.g., **/*.ts)
  • alwaysApply: If true, the rule is used without needing manual selection
  • referencedFiles: (Optional) Files used as examples or context for better AI responses
  • Body: The actual instructions shown to the AI when working in matching files.

To see which rules are active or to edit them:

  • Go to Settings → Rules
  • You’ll see both User Rules and Project Rules
  • Toggle, delete, or update them as needed

Now that you have got the structure down, let’s look at how developers can use Cursor Custom Rules to handle real-world problems.

Use Case 1: Enforcing Consistent API Validation with Zod

The Problem

Your team uses Zod for request/response validation across all service files, but devs often forget to include schemas or name things consistently.

Rule Example

---
description: Enforce Zod schemas in service layer
globs: ["src/services/**/*.ts"]
alwaysApply: true
referencedFiles: ["src/lib/zod-templates.ts"]
---

Always use Zod to validate both request and response payloads.
Reuse schema patterns from `zod-templates.ts`.
Do not allow untyped or loosely typed data to go through the service layer.

This makes the AI generate pre-validated, strongly typed service methods every time, no reminders or rework needed.

Use Case 2: Enforcing Consistent File Structure for Features

The Problem

Every new feature in your app should follow a clean structure like index.tsx, hooks.ts, types.ts, and api.ts, but different devs often structure things differently.

Rule Example

---
description: Enforce file structure for new feature folders
globs: ["src/features/**/index.tsx"]
alwaysApply: true
---

When generating or modifying a feature in `src/features`, make sure the folder contains:
- `index.tsx` as the entrypoint
- `hooks.ts` for all custom hooks
- `types.ts` for local types
- `api.ts` for all API calls

Follow existing naming and organization patterns.

With this rule, Cursor automatically scaffolds the correct file layout and encourages modular, maintainable code across your repo.

Use Case 3: Enforcing Unit Test Coverage with Vitest

The Problem

You're using Vitest, and every utility function should have a corresponding test file. Devs often skip writing them.

Rule Example

---
description: Ensure utility functions are covered by Vitest
globs: ["src/utils/**/*.ts"]
alwaysApply: true
---

Whenever a new utility function is created or modified, also create a corresponding `.test.ts` file using Vitest.
Follow the structure and naming conventions used in existing test files.

With this rule in place, AI writes tests along with your utilities, improving test coverage and helping juniors not skip QA steps.

Use Case 4: Auto-Wiring RPC Handlers with tRPC

The Problem

You're using tRPC, and you want every new route to follow a specific handler format with proper input/output typing.

Rule Example

---
description: Standardize tRPC handler creation
globs: ["src/server/api/**/*.ts"]
alwaysApply: true
---

When generating new procedures, use `z.infer` for input/output types.
Use the `protectedProcedure` or `publicProcedure` wrapper from the existing router setup.
Refer to `src/server/api/_utils.ts` for common logic.

With this, AI consistently generates boilerplate that aligns with your tRPC config without you needing to manually adjust every time.

Best Practices & Tips

Getting started with Custom Rules is easy, but getting them to stick and scale well with your team takes a bit of finesse. Here are some battle-tested tips to help you make the most of them:

Make Rules Iterative, Not Perfect

Don’t try to write the ultimate prompt on Day 1. Start small, even a 1-liner like “Use Zod in all services” can go a long way. Watch how Cursor responds, and improve the rule over time. 

Think of rules like code: ship early, refine often.

Be Specific in the Prompt

Don’t just say “use tests”, say “use Vitest and place tests in the __tests__ folder next to the source file”. The more specific the language, the more reliable the output. 

Use phrasing like: “Always start with...”, “Never skip...”, “Follow the pattern from...” etc.

Review Rules as a Team

If you’re on a team, treat your rules like coding conventions. Do quick async reviews, and align on when a rule should apply (alwaysApply: true vs. manual). This helps avoid confusion or overreach from the AI.

Keep It Human

Don’t over-engineer your prompts. Write it like you’re telling a junior dev sitting next to you. That’s usually the sweet spot.

Final Thoughts:

Custom Rules in Cursor are low-effort, high-impact. With just a few Markdown files, you can guide AI to follow your team’s coding style, enforce structure, and even auto-suggest best practices, all without writing extra logic or docs.

I have found that whether you’re working solo or on a big team, these rules let you offload the repetitive reminders and keep your codebase clean and consistent.

If you’ve ever wished AI could “just know how we do things around here,” this is how you get there.

Subscribe to Our Newsletter

RELATED ARTICLES

More from the engineering frontline.

Dive deep into our research and insights on design, development, and the impact of various trends to businesses.
The Bug That Doesn't Show Up in Code Review: Why Your Flutter Web App Reloads on Safari
The Bug That Doesn't Show Up in Code Review: Why Your Flutter Web App Reloads on Safari
A real-world look at how oversized images can trigger Safari reloads and iOS crashes in Flutter apps and how smarter image decoding prevents them.
From Prompting to Process: What Changed When Flutter Shipped Agent Skills
From Prompting to Process: What Changed When Flutter Shipped Agent Skills
This blog explores how Flutter Agent Skills improve AI-assisted development by combining official framework workflows with project-specific guidance for more consistent development.
Why Everything Your AI Builds Looks the Same
Why Everything Your AI Builds Looks the Same
This blog explores why AI-generated interfaces often look alike and explains how design systems, product context, and reusable engineering practices help teams build distinctive, scalable
How We Built the Missing Bridge from Code to Figma
Technology

Jul 10, 2026

How We Built the Missing Bridge from Code to Figma
This blog explores how AI-generated React apps get turned into fully editable, designer-ready Figma files by reading React Fiber instead of the DOM.
Building a Resilient Hybrid-Cloud Network with WireGuard HA, Route-Based Failover, and Deep Observability
Technology

Jun 27, 2026

Building a Resilient Hybrid-Cloud Network with WireGuard HA, Route-Based Failover, and Deep Observability
A practical breakdown of building resilient AWS-to-on-premises connectivity with WireGuard HA, active-standby failover, and deep packet-forwarding observability.
We Built a 114-Second AWS-to-Azure Failover. Here’s What We Learned
Technology

Jun 19, 2026

We Built a 114-Second AWS-to-Azure Failover. Here’s What We Learned
A practical guide to building a 114-second multi-cloud disaster recovery failover between AWS and Azure — what we built, what broke, and what we learned.
Cloud-Native and Cloud-Agnostic Are Not Ideologies; They Are Business-Stage Decisions
Technology

Jun 12, 2026

Cloud-Native and Cloud-Agnostic Are Not Ideologies; They Are Business-Stage Decisions
This blog explains how organizations can balance speed, scalability, and operational flexibility as they grow from startup to enterprise scale.

The Right Conversation Can Save You Six Months.

Whether you’re navigating AI adoption, modernizing legacy systems, or scaling a product - we start by listening. No pitch deck. No template. A real conversation.