coding standard guidelines
vibe coding
ai-assisted-development
software-architecture
development-best-practices
Imagine everything is going well in your development, you’re vibing with the code, and suddenly the AI suggests something that doesn’t follow your conventions; it duplicates logic, changes patterns, or mixes styles. It’s not being “capricious”—it’s lacking code-close context. The solution isn’t a 50-page manual, but rather short, living rules that the AI can read right where it works.
A context rule is a brief (Markdown) file that lives next to your code (for example, in .cursor/rules/
) and explains how a specific file or module should look and behave:
When your AI-powered editor (e.g., Cursor) generates or modifies code, it reads these rules as a guide to maintain consistency. It doesn’t replace linters or tests; it’s a lightweight specification that guides the AI.
Mini-example (.mdc):
1# Purpose 2Consistent REST responses. 3 4# Conventions 5- JSON with `{ data, error }`. 6- Errors include `code` and `message`. 7 8# ✅ Correct 9return res.json({ data: user, error: null }); 10 11# ❌ Incorrect 12Responding with `{ result }` in some endpoints and `{ payload }` in others.
Practical rule: if you’ve corrected the same type of AI output twice, it’s time to write a short rule.
Pick a “VIP” file. Something that sets the tone for the rest: routes.py
, UserService.ts
, Form.tsx
, theme.ts
, etc.
Ask the AI to draft the rule. In Cursor, with the file open, request:
1Generate a short rule to keep this file consistent. 2Include: purpose, 3–5 conventions, and at least 1 correct example. 3Don’t add prose outside the rule.
.cursor/rules/
folder and save as api-endpoints.mdc
(use a descriptive name).1# Purpose 2<what it standardizes and why> 3 4# Conventions 5- <concrete rule 1> 6- <concrete rule 2> 7- <concrete rule 3> 8 9# ✅ Correct 10<minimal snippet with the expected format> 11 12# ❌ Incorrect 13<typical snippet we don’t want>
1# Purpose 2Standardize REST endpoints with consistent responses. 3 4# Conventions 5- Respond with JSON `{ data, error }`. 6- Errors include `code` and `message`. 7- Avoid business logic in the controller; delegate to services. 8 9 10# ✅ Correct 11router.get('/users/:id', async (req, res) => { 12 try { 13 const user = await svc.getUser(req.params.id); 14 return res.json({ data: user, error: null }); 15 } catch (e) { 16 return res.status(400).json({ data: null, error: { code: 'USER_GET_FAILED', message: String(e) } }); 17 } 18}); 19 20# ❌ Incorrect 21Responding with `{ result }` in one endpoint and `{ payload }` in another.
Frontmatter YAML and globs are optional in this basic module.
To test the rule, ask the AI for a real modification to the VIP file (for example, “add GET /users
with pagination”) and check if it follows the rule. If it deviates, adjust the rule with a single change (delta prompting), for example: “add that successful responses use status 200 and errors ≥400; change nothing else.” Repeat until the suggestions are consistent and always add a section with correct and incorrect examples, since seeing what you do and don’t want helps the model lock in the standard.
Imagine you’re adding a new chat feature to your app using WebSockets. Here’s how you could use rules—create a file like chat-websocket.mdc
and outline the following:
1# Purpose 2Consistent errors and reconnection in WebSocket (chat). 3 4# Conventions (why) 5- `onerror` + `onclose` (visibility and stability). 6- Exponential backoff max 30s (avoid aggressive loops). 7- Encapsulated connection (avoid fragile global state). 8 9# ✅ Correct 10const socket = new WebSocket(URL); 11socket.onerror = (err) => { log('ws_error', err); attemptReconnect(); }; 12 13# ❌ Incorrect 14Just `console.error` without reconnection or encapsulation.
Now ask for “typing notifications” and the AI should maintain onerror + reconnection without further reminders.
To keep rules organized, store them in .cursor/rules/
with clear names and, if helpful, subfolders by module or layer. Version everything like code, commit them to git, and review them in PRs. In each PR, explain why the rule exists or changes (what problem it solves) so the team understands the context. Also, when writing and maintaining rules, avoid common pitfalls. If a rule gets long, trim it to the essentials and move large examples to a separate file. Replace vagueness (“clean code”) with concrete actions (“use try/catch
in async fetch
calls”). If there are duplicates or conflicts, unify or document precedence (“if it overlaps with X, X takes priority”). And don’t skip the test—ask for a real modification and verify the AI follows the rule.
Creating rules mid-development is often easier because you have real code to start from. If, instead, you’re repeating a well-known pattern (e.g., a simple REST API you’ve built before), you can prepare 1–2 rules from day one. There are also public collections of pre-written rules you can adapt (e.g., cursorrules
).
/Generate Cursor Rules
and refine the output, the better your prompts—and the better the AI will help you!You don’t need a perfect system to start. With a good rule in a key module, you’ll already notice less friction and more consistency. Create your first one today, test it, and tweak it with small changes; tomorrow, your AI will already be suggesting code more aligned with your project.