Getting the Most Out of Cursor IDE

I first started using AI coding tools with Continue, a plugin inside vanilla VSCode. I switched to Cursor in late 2023 and have used it daily since.

The switch was straightforward: Cursor’s LLM integration points are slicker, less buggy, and the paid subscription gives you access to their API pool for a capped monthly fee. When I was using Continue with OpenAI GPT-4, I was estimating up to $100/month in API costs during heavy usage. Cursor consolidates that into a single $20 subscription across all leading LLMs.

Here’s what I’ve found helps in complex projects.

Use Claude 3.5 Sonnet

After trying every option, Claude Sonnet is the best overall coding LLM. Cursor Pro uses their API key which is generally fast, but I keep my own Claude API key as a backup. When Cursor’s queue gets long (30-50+), I switch to my own key and use pay-as-you-go credits.

Document your codebase for the LLM

The LLM has a limited context window. The goal is to help it remember all required features and behaviour without losing track as you add new things. As of 2024, it can’t reliably hold more than 5-10 requirements in context, but you can help it remember more.

Code tests

Unit tests, Playwright, Cypress - these teach the LLM about expected behaviour and prevent regressions. Cursor can also help you write them. Tests are documentation that the LLM can read and verify against.

Requirements files

If you’re working on a feature with 20 requirements, Cursor will forget some of the old ones while you add new ones. Keep requirements in markdown files local to the component folder. When the LLM loses its way, point it back to the requirements and tests.

This mirrors how a product manager and engineer work together. You maintain the spec, the LLM builds to it.

Types and doc comments

Code doc formats that comment the start of files and functions. TypeScript type definitions. README files. All of these give the LLM more signal about usage and expectations.

Open parent folders

If you have multiple projects - backend and frontend, or different prototypes trying different approaches - open Cursor in the parent folder. It gets access to all sub-projects.

In your queries or cursor rules, specify which project is the main working directory and which are for reference. For example, one prototype works and the others are failed approaches the LLM should learn from.

Avoid Composer Mode (for now)

Cursor’s Composer mode covers a lot of ground but has a tendency to delete files or create duplicates. It’s experimental and not production-stable.

Use external docs indexing

Cursor can index external documentation - official API docs, articles about specific implementations, regulations, even GitHub repositories. It picks relevant items from the index to use as context in queries, like a RAG.

You can reference external articles and GitHub repos in queries: “create this inspired by these projects but use Y database instead of X.” You can’t do this in ChatGPT or Claude’s web interfaces - they don’t index external links into context the same way. This gives Cursor an advantage even for writing documents.

Indexing gotchas

Indexing can get stuck, both for local directories and external sources. Keep an eye on it and reindex anything that stalls.

Use .cursorignore

Large folders like node_modules or build directories slow Cursor down and reduce relevance. Create a .cursorignore file (like .gitignore) to exclude them. Without this, Cursor might suggest changes to build output instead of source files - a mistake that’s not immediately obvious and wastes time.

Cursor Rules

Cursor has a “Rules for AI” text field and .cursorrules files that act as system messages. Documentation is sparse and results are mixed - Cursor doesn’t always respect these as consistently as you’d expect. I expect this to improve.

Commit as you go

It’s tempting to chain back-and-forth queries and accept suggestions without stopping. In complex cases, this leads to breaking things, especially when multiple files change per suggestion.

Work on a feature branch. Commit after each meaningful change. You can rebase later to clean up. This gives you git bisect and git reset to debug regressions the LLM causes.