Six months ago, I worried about what “real programmers” would think. Now I realise we’re all just trying to build things that work.
I’m a good R programmer. I’ve dabbled with Laravel and front-end stuff.
But mastering modern web frameworks? Not worth my limited time when I can focus on building and marketing products that people actually use.
Being efficient doesn’t mean ignoring quality - it means achieving it through different means.
I wanted to build production-ready software without spending years mastering modern web frameworks. These ten practices helped me ship quality code quickly:
1. Always make a plan for more involved work
Cursor’s Plan mode is excellent, especially with Sonnet 4.5. It asks smart questions before executing—this is where the magic happens. Ans…
Six months ago, I worried about what “real programmers” would think. Now I realise we’re all just trying to build things that work.
I’m a good R programmer. I’ve dabbled with Laravel and front-end stuff.
But mastering modern web frameworks? Not worth my limited time when I can focus on building and marketing products that people actually use.
Being efficient doesn’t mean ignoring quality - it means achieving it through different means.
I wanted to build production-ready software without spending years mastering modern web frameworks. These ten practices helped me ship quality code quickly:
1. Always make a plan for more involved work
Cursor’s Plan mode is excellent, especially with Sonnet 4.5. It asks smart questions before executing—this is where the magic happens. Answering those questions helped me settle on the right stack (Next.js 15, TypeScript, Tailwind CSS) and avoid costly rewrites later.
The pattern: Think in Chat → Plan in Plan mode → Execute in Composer.
2. Claude Code will keep you honest
Install Claude Code and use it to critique your project from a different perspective. Be specific: ask it to evaluate architecture, security, code quality, and test coverage. Request a grade and recommendations. Save that to a .md file—you now have a continuous improvement roadmap you can convert into Issues.
This catches things Cursor won’t because it’s been embedded in your project the whole time. Fresh eyes matter, even if those eyes are AI.
3. Switch to Composer 1 for most coding tasks
Cursor’s in-house agent model is lightning fast, and code quality is barely different from Sonnet 4.5. The speed difference is massive.
My workflow: Plan thoughtfully (Sonnet 4.5) → Execute with speed (Composer 1).
4. Start with what you know, then convert
I built my latest project (Mindarin) as an R package first. With my data analytics background, I could give specific guidance (“use tidyverse packages”, “run devtools::check()”) and reach MVP in a day. Then I converted it to Next.js.
Starting in a familiar language means better prompts and faster iteration. The conversion step is trivial compared to figuring out what to build.
5. Implement tests from the start
I use test-driven development for every new feature—nothing gets built before its test. I’m running hundreds of tests now (unit, component, hook, E2E), and most were written by Cursor.
Tests aren’t overhead with AI coding—they’re documentation that runs. They also prevent the AI from breaking working features. When you’re shipping fast, tests are the guardrails that keep you from driving off a cliff.
6. Version control isn’t enough
The full GitHub ecosystem matters:
Actions: Run tests in parallel across multiple workflows. Catches regression before production. You might not need CI from day one, but there will come a point where you need it to prevent yourself from breaking things you’ve already fixed.
Issues: Your roadmap, labeled by priority. Have Cursor create them via GitHub CLI after planning conversations with Sonnet 4.5. Well-structured Issues become your project’s memory.
Projects: Organize Issues into P1/P2/P3 views. Always know what to work on next. When I run out of fixes to apply in Cursor, I know exactly where to pull the next job from.
7. Always ask questions in Ask mode
Seems obvious, but don’t brainstorm in Agent mode—it’s prone to action and will start coding before you’re ready.
Use Ask mode (with Sonnet 4.5) for thinking through problems. It can still read your files and search the web, but won’t touch your code. Build a plan from these conversations, then execute.
Think of it this way: Ask mode is for architects, Agent mode is for builders. Get the design right before you break ground.
8. Don’t let debugging slow you down
I’m pushing to main dozens of times a day. Most CI runs fail on first attempt. Cursor fixes things fast, but it’s way more effective if you feed it the actual logs.
Solution: Ask Cursor to write a script that downloads logs from your most recent failed CI run. Point it at those logs when troubleshooting. Beats copy-pasting from the web, and Cursor can pattern-match errors across your entire codebase.
9. Stop writing documentation manually
I haven’t written a commit message in three months. Cursor generates them from my staged changes, writes my README from the codebase, and creates inline docs as I code. The time I save goes into building features users actually care about.
Documentation is a solved problem now. Your brain should focus on what to build, not how to describe it.
10. Speak your thoughts out loud
Cursor has voice mode now, but I prefer superwhisper—it understands me first try, filters out “um” and “actually,” and its free tier is generous.
Speaking forces you to provide more detail than typing. You naturally explain context, edge cases, and intent. Better prompts = better code.
Those are my top 10, but I’m definitely still learning.
What am I missing? What works differently for you?
I’d especially love to hear from people further along—what changes after the first year of vibe coding?
(I built Mindarin - Chinese learning app with memory palaces - entirely with this approach. Happy to share more about the tech stack if anyone’s curious.)