When Cursor first came out, I gave it a try - but it didn’t stick. I found myself going back to VSCode and PyCharm. Recently, though, the noise on X convinced me to try Cursor out one more time, and I'm glad I did because something just clicked. Now, I’m loving coding with Cursor, and I realize the issue the first time around wasn’t the AI itself - it was how I was working with it.
Initially, I complained that the Composer changed too much of my code, and I preferred individually reviewing each edit, ChatGPT-style, before deciding what to include. I wanted to actively incorporate changes rather than passively skimming them. In retrospect, the very power Cursor offers - making large-scale, direct code edits - was what frustrated me. It’s like giving an over-eager intern developer complete freedom without proper guardrails. It was my mistake, not Cursor's.
This time, I built a structured workflow to guide Cursor in ways that boost productivity without going rogue.
When to Use Cursor
- Best for experienced developers who are comfortable reviewing code
- Great as a “speed-up” tool, not a complete code generator
- Ideal for smaller, focused tasks like unit tests or refactoring
- Handy for exploring new languages when you already understand coding fundamentals
- Performs particularly well on certain frameworks (e.g., Flutter, Next.js)
Key Features & Shortcuts
Features
-
Autocomplete
- Context-aware, using your entire codebase for suggestions.
- Hit Tab to accept.
-
AI Chat
- Offers quick Q&A and code edits.
- Applies changes straight to the file.
-
Composer
- Generates or updates multiple files based on a single instruction.
- Very powerful but needs solid guardrails.
-
Agents
- Facilitates multi-file edits, terminal commands, and full project context.
- Can automate big tasks; just ensure your Agents are well-configured.
- Error-prone if the agent is not configured correctly
-
File Tagging
- Control exactly where AI should make changes.
-
.cursorrules
- A configuration file to define consistent coding, naming, and formatting rules.
“Context, Context, Context”
Cursor thrives on context. If you don’t set up clear boundaries and good documentation, it will hallucinate. Think of it as a junior dev that you haven’t properly onboarded. You must define a strong boundary of context around your project. The more you feed Cursor with well-structured docs, the better (and more reliable) its output.
Prompting Cursor
I used to spend a lot of time crafting in-depth prompts for ChatGPT, explaining code bases, constraints, and patterns. When it came to cursor, I took the fact that it had access to code context for granted, and I started using single-line instruction - “fix this code” - assuming it had enough context just by reading my files. That’s a recipe for frustration. If you don’t offer the same level of detail you’d give a human teammate, Cursor might “improve” code in ways that break subtle but critical patterns.
Good Prompting Practices
-
Discuss Requirements
- Spell out what you need - like acceptance criteria or constraints.
-
Provide Context
- Include relevant code snippets, hidden dependencies, and usage patterns.
- Tag Docs in the Composer
-
Review Changes Incrementally
- Don’t blindly accept changes.
- Keep commits small and easy to review.
-
Explain Patterns & Constraints
- If there’s a custom logger or a specific design pattern, mention it.
- Avoid “one-liner” instructions for big tasks.
Tips for Using Cursor Effectively
-
Use LLMs to Explain Code
- Great for learning and documentation.
- “Explain like I’m a beginner” reveals hidden logic or patterns.
-
Add Comments to Your Code
- Improves readability and helps AI or teammates understand your intent.
-
Duplicate & Modify Existing Functionality
- Copy a working code snippet and have Cursor adapt it.
- This gives Cursor relevant context as well as patterns of how you like to code for better results.
-
Debugging
- For each update, open a new Composer, attach files with issues, and paste the errors.
- Review the diff before applying any changes.
-
Use Git
- Always have your code under version control.
- Commit frequently so you can revert if something breaks.
-
Focus Changes
- Use file tagging
@
in the composer window to pinpoint where changes should occur. - Avoid too many large-scale edits at once.
- Use file tagging
-
Don’t Rely on Cursor for Architecture
- It can propose ideas, but architectural decisions need human oversight, especially for database schema design.
-
Consult Other AI If Stuck
- Sometimes GPT-o1 or Claude can see solutions Cursor misses.
- Provide errors and context for the best results.
-
Keep Generations Small and Focused
- Big requests lead to big confusion. Think incremental.
-
Tab Completion is Underrated
- For experienced developers, Cursor’s line-by-line suggestions are often more valuable than Chat.
Establishing a Workflow
1. Start with Problem Statement & Requirements
The goal is to achieve clear alignment before any code is written. This helps prevent Cursor from making assumptions or going off track.
- Brain Dump First
- Use Claude or another model to turn your raw ideas into structured text.
- Discuss the Problem Space
- Clarify the issue and define acceptance criteria.
- Document Key Constraints
- Outline anything that might trip up the AI (legacy code, unique design patterns, etc.).
- Aim for Shared Understanding
- Whether you’re solo or on a team, ensure everyone (including Cursor) knows the end goals.
2. Create Design Documentation
The goal is to create a roadmap that both you and Cursor understand and can reference.
- Refine the PRD
- GPT-4 or GPT-3.5 can help with detailed formatting.
- This PRD becomes your North Star for the entire project.
- Use a Standard Template
- System architecture overview, component interactions, data flow diagrams, API specs, DB schema.
- Review & Iterate
- Ask Cursor to validate technical approaches.
- Document constraints and known dependencies.
5. Leverage Existing Code Templates
- Start with Boilerplate
- Next.js, FastAPI, Auth, DB, payments - whatever fits your stack.
- Build on What Works
- Save time by using proven patterns.
- Cursor can adapt these quickly with fewer surprises.
7. Research Packages
- Add Official Docs to Cursor
- Next.js, Supabase, etc.
- Models often have outdated info - explicitly referencing docs helps accuracy.
- Tag Docs
- In the Composer, use
@
to link relevant docs for context.
- In the Composer, use
- Keep a
docs/instructions.md
- Include code examples, usage patterns, file structures.
You can run brew install tree
to get a tree view of your project. To get a good enough tree use tree -L 2 -I 'node_modules|dist|build|coverage|.git'
Here is a prompt to be passed into models like o1 to add details to the original PRD:
Help me add details to the original PRD to provide clear alignment for the developers who will implement the project:
- Do not create actual code, just the PRD.
- Include the file structure in the document.
- Include all provided documentation (with both example code and responses, as these are important context).
The instructions.md file should be updated as you code out the project.
Initial Prompts & Cursor Rules
cursor.directory
allows you to copy tech-specific prompts. These are prompts for initial prompts before prompting anything in Cursor. Copy and add a .cursorrules
file in the root of your project.
The instructions in the .cursorrules
file will be included for features such as Cursor Chat and Ctrl/⌘ K. The more specific your rules for your project, the better. It drastically improves Cursor's output.
3. Implement in Phases
- Define Clear Scope
- Break tasks into manageable chunks aligned with your design doc.
- Reference Docs
- Keep returning to your documented constraints and acceptance criteria.
- Small, Focused Changes
- Reduces risk and makes it easier to review.
4. Continuous Testing
- Mixed Testing Strategy
- Automated tests (unit/integration) + manual validation.
- Document Test Cases
- Make sure everything ties back to requirements.
- Validate Against Requirements
- If it doesn’t pass, don’t just rely on Cursor’s guess - dig deeper.
Debugging with Cursor
When you’re stuck on a bug, try telling Cursor to add debug logs. Cursor will insert systematic logging, track state changes, and suggest next steps. Then you can paste the new logs or errors back into Cursor to improve its context.
Best Practices
-
Enforce a Structured Workflow
- Any consistent process is better than none.
- Share your workflow with Cursor at the start of each session.
-
Communicate Before Coding
- Explicitly say, “Do not write code yet. Let’s discuss requirements.”
- Use design docs as the conversation anchor.
-
Maintain Context Continuity
- Reference previous steps often.
- Update Cursor about manual edits so it doesn’t become “blind” to new changes.
-
Break Down Work
- Limit the scope of each interaction.
- Focus on one component or phase at a time.
-
Iterate & Document
- Don’t push forward if confused; it’s okay to revisit requirements.
- Keep a record of decisions, especially if you’re on a team.
-
Review Code Thoroughly
- Even small snippets can introduce nasty bugs.
- Make use of diff views,
git diff
, etc.
-
Keep Generations & Edits Small
- Quick, incremental tasks prevent “spaghetti” code from creeping in.
-
Stay Open to Other AI
- If Cursor is stuck, GPT-4, Claude, or others might have fresh perspectives.
- Share the context and errors with them too.
Troubleshooting Patterns
-
Step Back
- If something goes off the rails, revert to your last working commit.
- Revisit your documentation or reset the conversation.
-
Clarify Context
- Reattach relevant files or constraints.
- Double-check your design docs.
-
Break Down Further
- If a task is too big, subdivide.
- Address one function or file at a time.
-
Document and Learn
- Keep a log of failed attempts and how you resolved them.
- Update your
.cursorrules
or instructions accordingly.
Conclusion
Cursor can be a brilliant coding companion - if you treat it like a junior developer who needs direction, documentation, and incremental tasks. The key is structured workflow, clear requirements, and thorough code review. With the right guardrails, Cursor speeds up repetitive tasks, offers fresh insights, and helps you ship code faster than ever.
Overall:
- Good prompts and detailed context keep things on track.
- Small, focused changes are easier to review.
- Documentation matters - spend 80% of your time preparing and guiding, and 20% coding.