If you've ever felt like your AI coding assistant writes code that doesn't quite fit your project's style or ignores your security policies, you're not alone. The fix is simple: create a custom rules file. Tools like Cursor, Windsurf, and GitHub Copilot now support user-defined rules that tell the AI exactly how to behave. This tutorial will walk you through creating a .cursorrules file (the format works for most AI coding tools) and give you ready-to-use patterns.
Step 1: Understand the Rules File Format
Rules files are simple text files (usually .cursorrules or .windsurfrules) placed in your project root. They use a plain-language syntax to set context, preferences, and constraints. Each line or block is interpreted as a directive. Some tools also allow JSON or YAML, but the universal approach is a Markdown- or plain-text file with explicit rules.
Create an empty file named .cursorrules in your project root. This is where the AI will look for instructions before generating code.
Step 2: Write Project Context Rules
Start by telling the AI about your project. Add these lines to your file:
# Project: E-commerce API (Node.js + Express + MongoDB)
# Description: REST API for managing products and orders
# Style: Use async/await, not callbacks. Prefer named exports.
# Database: Use Mongoose for MongoDB operations
# Authentication: JWT-based with refresh tokens
Step 3: Enforce Code Style and Conventions
Now add concrete style rules that the AI must follow. Use imperative sentences for clarity:
# Code style rules
- Use 2-space indentation, never tabs.
- Prefer 'const' over 'let' and never use 'var'.
- All function parameters must have TypeScript types.
- No magic numbers – define constants at the top of the file.
- Use template literals instead of concatenation.
- Error handling: always wrap async functions in try/catch and pass errors to next().
- File naming: use kebab-case for files, PascalCase for components/classes.
- Comments: use JSDoc for public APIs, inline comments only for complex logic.
Step 4: Add Security and Best Practice Constraints
Prevent the AI from generating common vulnerabilities by adding security rules:
# Security rules
- Never hardcode secrets, API keys, or passwords.
- Validate all user input using Joi or Zod.
- Use parameterized database queries (no string concatenation).
- Set helmet middleware for HTTP headers.
- Rate limit API endpoints.
Step 5: Provide Examples (The Secret Sauce)
The most effective rules include specific examples of what you want. Add a section like this:
# Example of an acceptable controller function
# async function getProduct(req, res, next) {
# try {
# const product = await Product.findById(req.params.id);
# if (!product) return res.status(404).json({ error: 'Not found' });
# res.json(product);
# } catch (err) {
# next(err);
# }
# }
Step 6: Test Your Rules
Restart your AI tool so it reloads the rules file. Then ask it to generate a new piece of code, e.g., “Create a GET endpoint for orders with pagination.” Review the output. Does it use async/await? Two-space indentation? Error handling? If not, refine your rules.
Iterate until the AI's output feels like it was written by a team member who knows your codebase.
Beyond .cursorrules
Similar concepts exist for other tools:
- GitHub Copilot: Use a
.github/copilot-instructions.mdfile. - Windsurf: Uses
.windsurfrulesin the root. - Codeium: Supports
.coderulesor inline prompts.
Check your tool's documentation for exact file paths and syntax.
By following these steps, you'll reduce code review friction, improve consistency, and make your AI assistant a true team player. Start with a minimal rules file and expand as you discover patterns the AI misses.
I've been experimenting with .cursorrules but found it tricky to balance specificity without breaking the assistant's flow. How do you handle versioning these rule files?