10 Best Practices for Writing AI Coding Rules
Practical tips for writing rules that make Cursor, Claude Code, and Windsurf consistently produce better code for your project.
Why rule quality matters
Bad rules produce bad code. Vague instructions like "write clean code" or "follow best practices" give the AI nothing actionable. The result is generic output that doesn't match your project's conventions.
Good rules are specific, example-driven, and scoped. Here are 10 practices that make your AI coding rules consistently effective — whether you're writing them for Cursor, Claude Code, Windsurf, or any other tool.
1. Be specific, not generic
Bad:
Write clean, maintainable code.
Good:
- Use named exports for all React components
- Keep functions under 50 lines
- Extract shared logic into hooks (src/hooks/)
- No inline styles — use Tailwind utility classes
AI tools take instructions literally. "Clean code" means nothing to them. "Named exports, under 50 lines, Tailwind only" gives them exact constraints to follow.
2. Show examples of desired output
Rules tell the AI what to do. Examples show it how. Include at least one concrete code example for every major pattern:
## API route pattern
Every API route follows this exact structure:
export async function POST(request: Request) {
try {
const body = await request.json();
const validated = schema.parse(body);
const result = await db.insert(users).values(validated);
return Response.json({ data: result });
} catch (error) {
if (error instanceof ZodError) {
return Response.json({ error: error.message }, { status: 400 });
}
return Response.json({ error: "Internal error" }, { status: 500 });
}
}
When the AI sees this example, it mirrors the exact structure — import pattern, error handling shape, response format — every time.
3. Include your tech stack and versions
Always start your rules with an explicit tech stack declaration:
## Tech stack
- Framework: Next.js 15 (App Router only, no Pages Router)
- Language: TypeScript 5.7 (strict mode)
- Runtime: Node.js 22
- Database: Drizzle ORM + PostgreSQL
- Styling: Tailwind CSS v4
- Testing: Vitest + React Testing Library
- Package manager: pnpm (not npm or yarn)
Without this, the AI guesses — and it often guesses wrong. Specifying "Next.js 15 App Router" prevents it from generating Pages Router code. Specifying "pnpm" prevents npm install commands.
4. Define file naming conventions explicitly
## File naming
- Components: kebab-case (user-profile.tsx, not UserProfile.tsx)
- Hooks: use-prefix, kebab-case (use-auth.ts)
- Utilities: kebab-case (format-date.ts)
- API routes: route.ts inside kebab-case folders (api/user-profiles/route.ts)
- Types: kebab-case with .types.ts suffix (user.types.ts)
- Tests: same name with .test.ts suffix (format-date.test.ts)
File naming is one of the most common inconsistencies in AI-generated code. Without explicit rules, you'll get a mix of PascalCase, camelCase, and kebab-case files in the same project.
5. Specify error handling patterns
## Error handling
### API routes
- Wrap all handlers in try/catch
- Return { error: string } with appropriate HTTP status
- Log errors with logger.error(), never console.log()
- Include request ID in error responses for debugging
### React components
- Use error boundaries for component-level failures
- Show user-friendly error messages, not stack traces
- Report errors to the error tracking service
### Database operations
- Wrap transactions in try/catch with rollback on failure
- Never expose raw database errors to the client
Error handling is where AI tools struggle most without guidance. They'll either ignore errors entirely or add excessive try/catch blocks. Be explicit about your patterns.
6. Document your API response shapes
## API response format
Every API endpoint returns one of these shapes:
Success:
{ data: T }
Error:
{ error: string }
Paginated:
{ data: T[], meta: { total: number, page: number, perPage: number } }
Never return raw arrays. Never return bare strings. Always use the { data } wrapper.
Consistent API responses make frontend code predictable. Without this rule, the AI invents a new response shape every time.
7. Set boundaries on what the AI should NOT do
The "do not" section is often more important than the "do" section:
## Do NOT
- Do not use the Pages Router — we are fully on App Router
- Do not use default exports (except for page.tsx and layout.tsx)
- Do not use CSS modules or styled-components — Tailwind only
- Do not install new dependencies without asking first
- Do not use any as a TypeScript type
- Do not use console.log — use the logger utility
- Do not commit .env files or secrets
- Do not use string concatenation for SQL — use parameterized queries
AI tools are eager to help. Without boundaries, they'll install packages, switch frameworks, or take shortcuts that break your conventions.
8. Keep rules under 500 lines
Long rules files cause two problems:
- They dilute the important instructions with noise
- They consume context window tokens that could be used for actual code
Guidelines for size:
| Rules file | Target length |
|---|---|
| Core conventions | 100-200 lines |
| Domain-specific rules | 50-150 lines |
| Tech stack declaration | 20-50 lines |
| Total across all files | Under 500 lines |
If your rules exceed 500 lines, split them into focused files. See the Cursor rules guide for organizing rules into folders.
9. Version your rules alongside your code
Rules should live in version control. When you change a convention — say, switching from REST to tRPC — the rules update should be in the same PR as the code change.
With localskills.sh, versioning is automatic:
# Every publish creates a new version
localskills publish --team my-team --name api-conventions -m "Switch to tRPC patterns"
You get full version history in the dashboard. If the new convention doesn't work out, roll back to any previous version with one click.
10. Share and reuse rules across projects
The biggest waste in AI coding is writing the same rules for every project. Your TypeScript conventions, error handling patterns, and security rules are the same across most of your team's repositories.
Publish them once, install everywhere:
# Publish
localskills publish --team my-team --name typescript-conventions
# Install in any project
localskills install my-team/typescript-conventions --target cursor claude windsurf
One source of truth. Every project, every tool, every developer — same rules.
Read about sharing rules across tools or learn about standardizing AI coding across your team.
Better rules mean better AI-generated code. Publish your first skill and start sharing best practices across your team.
npm install -g @localskills/cli
localskills login
localskills publish