Cooking With Cursor

Cooking with Cursor: A Recipe for Successful Cursor Development

cursor recipe illustration

When I say cursor development, I mean really to say developing with Cursor. I say ‘developing with Cursor’ as if to imply that we are equal partners in the process, in the same way that I might say that I am cooking supper with one of the kids.

One of us is doing a lot of the organising, preparing the recipe, getting things in place, tasting the spoon and plating things up.

The other is ready to pour all the ingredients in at once, jump around steps in the recipe and not tidy up after themselves.

I leave it as an exercise to the reader as to which of us you think fulfils each role.

In reality the slapdash approach can be fun when the end result is not so important, but when there is a soufflé on the line it’s important to get the process right.

Preparing the Recipe

Generally I find working in Cursor at its easiest when I have spent some time planning what we are about to embark upon. If you have a very well defined ticket to work on, this is a good start. Alongside a good ticket, or even instead of, I find a good starting point looks something like:

We are about to $describe_task_briefly 
Before we do this, I want to write a plan in a new file called plan.md
In the file, we will come up with the proposed checklist of changes 
necessary to meet this task. 
We will list the files that we need to modify, 
and what functions need to be added.

We will also need to add the corresponding tests

Write a bullet point or points as to what needs to be done in each function.

We will go through the file and adjust as necessary

DO NOT write any code until I have agreed to the proposal outlined in the plan.md file

This needn’t take longer than 10 minutes, but it’s 10 minutes well spent.

Putting Things in Place

Having iterated over the plan.md and got to a point where I am satisfied, I’ll start a new chat.

Starting a new chat is important - it flushes the context of all the proposals that were no good, and allows us to get on with the task at hand.

Starting a new chat, I would say something like:

Referring to @plan.md, I would like to make the first change listed.
We need to modify @filename and create the test case necessary to cover it.

Typically this may take a couple more conversational prompts along the way.

Tasting as You Go

When we have a passing test case or cases that make sense, our task is done.

Maybe a test alone is not sufficient. In some cases it might even be worthwhile to get Cursor to create a throwaway script to use the function just added, and let you observe the output. This needn’t be a file to add to git, but can prove invaluable in observing inconsistencies or unexpected behavior.

Think of these throwaway scripts as your “taste tests” - quick validation that what you’ve cooked actually tastes right before serving it to production.

In any case, we can go on and mark our step complete:

We can mark the first change as completed in @plan.md

Smashing 🚀 we are well on our way. After having done this loop, we can close that chat and start a new one.

Leaving Breadcrumbs

Sometimes we don’t actually want to be the cleanest of cooks - we might want to leave some breadcrumbs behind us that will help us later on. If we think we might need to refer back to something later on from a current task, it’s worth asking your agent to make a note in the plan.md:

We made a decision in implementation of $thing that will be important later
Add a summary of this under the heading ## Important Information

These breadcrumbs become invaluable when you return to the kitchen weeks later, wondering why you chose one approach over another.

Common Disasters (and Recovery)

The Runaway Recipe: When Cursor starts making changes you didn’t ask for or begins refactoring unrelated code, stop immediately. Close the chat and start fresh with more specific instructions.

Mystery Meat: If Cursor references functions, imports, or APIs that don’t exist, it’s hallucinating. Don’t let it continue - provide the real context or existing patterns.

Overcooking: If you’re deep in debugging with no clear progress, it’s better to start a new chat than continue, hoping for the best.

Always be ready to hit stop in a conversation

Key Observations

Clean Context: Cursor needs clean context in order to minimise the mis-steps in writing code.

Tim’s Rule: If a conversation during implementation phase has surpassed 30 turns, revert changes and start the conversation again with clearer defined goals.

Plan then Code: Cursor will, without guidance, jump in and start making code changes. It may create its own little todo section in the chat, but you are merely a spectator to the list. Be strict about the planning phase.

Choose Your Sous Chef Wisely: LLM choice is important. Gemini-2.5-pro is generally my daily driver, but anecdotally I find its test cases a little too simplistic. Claude-4-sonnet tends to do a much better job of comprehensive tests.

Bon appétit! 👨‍🍳