How I work with Cursor (+14 hours of recordings)

How I Work with Cursor

Recorded Cursor Development Sessions

I’ve recorded 14+ hours of unedited live coding sessions showing how I work with Cursor whilst building a new prototype app. These aren’t polished tutorials, they’re just raw development sessions where you can see the actual problem-solving process, mistakes, iterations, and how Cursor AI integrates into my workflow.

You’ll see me using the planning sessions, context management, external package research, screenshot-driven UI development, and all the other techniques mentioned below as they naturally occur during development. During this I worked exclusively with Claude Sonnet 4 (thinking mode) default agent (sometimes using MAX).

The recordings show both the successes and the moments where we need to step back and try a simpler approach. I plan to keep this series going and record each time I’m working on the app. You can find the recordings here (the only videos on the channel):

What I’ve built during these sessions

A full-stack chat application with real-time AI conversations using TypeScript throughout. The backend is an Express API with Prisma ORM, MySQL database, and Socket.IO.

It integrates with OpenAI’s Responses API and includes user management with JWT authentication. The frontend is a React SPA with Material-UI providing chat interfaces and admin panels with DataGrid components.

The entire stack runs in Docker containers with hot reloading. This is currently an ongoing development prototype project where I continue to iterate and add features. Maybe I will decide to do something with it later on.

Here are the specific techniques and workflows I’ve developed for getting the most out of Cursor AI in a TypeScript project:

Hot Reloading & Development Environment

Hot reloading is a must for my workflow. I use Docker for frontend, backend, database. React Vite SPA frontend, tsx for the Node.js JSON API backend, and my database is in MySQL. This means I have a rule which gives Cursor the instructions on how to run MySQL commands to pull data into the context or to create records. It can also restart containers and read docker logs to pull troubleshooting information into the conversation context. Once I’ve accepted Cursor’s changes after reviewing the diffs, the code updates. Then I can instantly check it out.

Framework Choices & Philosophy

When working with AI, I’ve discovered that opinionated frameworks work much better than flexible ones. For existing codebases where design patterns and architecture (Angular Material UI) are already established, Cursor is amazing to work with Angular. This is because I think maybe AI likes opinionated frameworks and Angular is exactly that.

Going against this though, for new projects, I’ve now picked React over Angular. My thought pattern being there’s probably 10x the amount of training data for React whether it be problems, tutorials, etc. There are also a lot of great libraries available for React as well which the Angular ecosystem is missing.

I picked Material Design MUI for the same reason - it’s opinionated. I don’t know much about UI, and the LLM has less stress when working with it. They also have great documentation. Having an opinionated framework removes a lot of decision-making overhead for both me and the AI.

Cursor Tab

Cursor tab - what can I say? It works incredible with interfaces. When implementing into classes it will pre-fill almost the entire implementation. I’m also using Prisma which automatically generates types for your data model so it creates the correct methods.

I find if I have the files it will need to look at open in other tabs, it works even better. The jump to next file is great. Tab works fantastic if you have established patterns in your app. For example I have Prisma ORM, repositories, services, controllers, and routes all following consistent patterns.

Why TypeScript?

I use TypeScript for both frontend React and backend Node.js due to Cursor Tab working incredibly with TypeScript. This is especially true when you have interfaces lined up which you need to implement.

Cursor plays nicely with the TypeScript LSP integration. Whether it be picking up linter errors and iterating over them during development or during tab completion.

It just seems smooth for some reason.

Why Go?

I’ve also worked with Go which has a great LSP. It behaves the same way as TypeScript with Cursor. The LSP integration is excellent and provides the same smooth development experience.

External Package Research

If I’m having issues with an imported module, I will git clone the source code. Then I get Cursor to read the files with the run command tool to try and look at the types and see why we’re getting a specific error. I did this with a very recent version of MUI X DataGrid.

If there’s a new feature such as the OpenAI responses API and the model you’re using won’t have many examples on it (or may not know it at all), I will git clone the source code. Then I get Cursor to run the terminal command tool to do some research. It outputs this into a markdown file which can be referenced.

I’m amazed when working with it this way. I then just verify the findings. I paste in the actual API response type from online docs and then get it to recheck. Now going forward I have established patterns using it and can always reference that markdown file.

Context Management & Planning

I add as much context as possible up front. I will tell the agent to use that context if it has it. If I’m implementing a large feature I will first state we are in a planning session and we are not currently doing any coding, just discussing.

I will detail what we need to do, provide code context, screenshots if needed. I get it to ask me many questions. Sometimes these back and forths can go on for a good while. Then we will make a plan in markdown with very specific micro tasks and start to work through this. It works very well.

I do find Cursor sometimes has an issue editing the markdown file. So I now tell it to complete tasks 1.1 - 1.3 etc and then I’ll mark them complete. Then we go to the next task.

UI Development with Screenshots

If I want a specific style from another site I’ve seen, I will paste the screenshot in and have a discussion to implement it. I also try to sometimes get the LLM very excited about specific things when working with UI. To me that can be very experimental work.

As long as my backend is solid when working with a SPA and JSON API, I am a little looser with strictness on the frontend code. I can copy rendered React code from the web console alongside screenshots for assistance. The component gets tagged in for better context.

Problem-Solving Strategies

Sometimes if we are looping and not fixing an issue, I stop. I give it all the context again and say we don’t need to follow this design.

I ask Cursor how to achieve the same thing but in a simpler fashion. If I’m quite far into a chat, I will retag my rules. For example: “We need to query the @database.md for x and y.” I will always pass it my Prisma schema file whenever we start working on anything.

Boilerplate Generation

If I need to add a new entity (for example I currently have chats, users, user sessions), let’s say I wanted to add documents, I would build the boilerplate.

I say “Look at the pattern followed for @repositories, @services etc, and implement documents using the same patterns.” Here would be further specific information about that entity. This approach leverages the established architectural patterns and keeps everything consistent.

4 Likes

Thanks for taking the time to share thoughts. It helps