Getting started with Cursor: a practical guide
# Getting Started with Cursor: A Practical Guide
I remember the exact moment I rage-quit my IDE. I was refactoring a React component, and my cursor was bouncing between three files, copying snippets, pasting them, fixing imports, and praying I didn’t break the state management. After the fifth manual edit, I thought: *There has to be a better way.* That’s when I tried Cursor.
Cursor is a code editor built on top of VS Code, but it’s not just a reskin. It integrates AI directly into your workflow—think GitHub Copilot on steroids, with context-aware chat, inline editing, and a terminal that can help you debug. After using it daily for three months on a production Node.js app, here’s what worked, what broke, and how to get started without wasting a weekend.
## Why Cursor (and When to Skip It)
Cursor’s killer feature is **context**. Copilot suggests completions based on the current file. Cursor can see your entire project’s structure, open files, and even your terminal history. If you’re working on a codebase with tangled dependencies—like a monorepo with 20 packages—Cursor’s AI won’t hallucinate as often.
But it’s not perfect. Cursor’s AI can generate code that *looks* correct but silently introduces edge-case bugs. And if you’re on a low-end laptop, the AI suggestions can feel sluggish (I saw 1-2 second delays on a 2019 MacBook Pro). For small scripts or tutorials, VS Code + Copilot is fine. For real-world refactoring, Cursor shines.
## Getting Started: Installation and Setup
1. **Download Cursor** from cursor.com. It’s free for individuals (with a 500 AI request/month limit). I paid for the Pro tier ($20/month) for unlimited requests—worth it if you’re coding 6+ hours a day.
2. **Import your VS Code settings**. Cursor is built on VS Code 1.85, so your keybindings, themes, and extensions carry over. When you first open Cursor, it asks if you want to import settings from an existing VS Code installation. Say yes. I lost an hour reconfiguring my keybindings because I clicked “No” by accident. Don’t be me.
3. **Configure the AI model**. Go to `Settings > Cursor > AI`. The default model is `gpt-4o`, but I switched to `claude-3.5-sonnet` for technical tasks—it’s better at reasoning about code structure. You can also set a custom API key if you have access to other models.
## The Three Cursor Modes That Saved My Week
Cursor has three interaction modes: **Chat**, **Inline Edit**, and **Terminal AI**. Here’s how I use each one.
### 1. Chat: The Context-Aware Assistant
The Chat panel (Ctrl+K) is like having a senior dev sitting next to you. But unlike Copilot Chat, Cursor’s chat sees your entire project. I tested this by asking: “Why is this API endpoint returning 500?” while my cursor was on a file in `/services/payment.ts`. Cursor replied: “Because your `validateWebhook` function in `/utils/webhooks.ts` is throwing an unhandled error on line 47—you forgot to catch the `HMAC` mismatch.”
That level of context is spooky. But here’s the catch: **Cursor’s chat can’t run your code**. It only reads static files. So if your bug is a runtime race condition, chat will guess wrong. I wasted two hours chasing a ghost bug because Cursor said “the issue is in the database connection,” but the real problem was a missing `await` in a loop.
**Pro tip**: When using Chat, always include the error message verbatim. Cursor is terrible at guessing error messages from memory. Copy-paste the exact stack trace.
### 2. Inline Edit: The Refactoring Machine
Inline Edit (Ctrl+I) lets you select code and ask for changes. This is where Cursor earns its keep. I had a 200-line function that handled user authentication, logging, and email sending—a classic God function. I highlighted the whole thing and typed: “Refactor this into separate functions: one for auth, one for logging, one for email. Keep the same behavior.”
Cursor generated three functions in under 10 seconds. But here’s what broke: it **forgot to update the import statements** in the original file. The new functions were defined, but the original code still called the old monolithic function. I had to manually wire them together. So always review the generated code for missing imports—Cursor’s AI is great at local changes but loses track of the big picture.
**Real example**: I asked Cursor to “add error handling to this Express route.” It wrapped the handler in a try-catch, but it also **deleted my custom error logging middleware** because it thought the try-catch was sufficient. That cost me a production incident. Always diff the changes before hitting “Accept.”
### 3. Terminal AI: The Debugging Sidekick
Cursor’s terminal (Ctrl+`) has an AI button that explains errors. I typed `npm run test` and got a cryptic `ERR_MODULE_NOT_FOUND`. I clicked the AI button, and Cursor said: “Your `package.json` has a `type: module` field, but your test file is using CommonJS `require()`. Either rename the test file to `.mjs` or add `"type": "commonjs"` to the test’s subdirectory.”
That saved me 20 minutes of Googling. But the terminal AI **cannot execute commands**. It only reads the terminal output. If your error is a network timeout, Cursor will say “check your internet connection” which is useless. It’s best for syntax and configuration errors.
## Practical Workflow: Refactoring a Real Project
Let me walk you through a real session. I had a Next.js app with a messy API route:
```javascript
// pages/api/user.js
export default async function handler(req, res) {
const { method } = req;
if (method === 'GET') {
// 50 lines of user lookup
} else if (method === 'POST') {
// 60 lines of user creation
}
// ...and so on for PUT, DELETE
}
```
I wanted to split this into separate files per HTTP method. Here’s exactly what I did:
1. **Highlight the entire handler** (lines 1-200).
2. **Press Ctrl+I** to open inline edit.
3. **Type**: “Split this into separate handlers: one for GET, POST, PUT, DELETE. Each handler should be in a separate file under `pages/api/user/`. Create the files and update the imports.”
4. **Cursor generated** four files: `get.js`, `post.js`, `put.js`, `delete.js`. It also created a new `index.js` that imported them.
5. **But here’s the flaw**: Cursor **did not delete the original file**. So I ended up with both `pages/api/user.js` (the old one) and `pages/api/user/index.js`. The router got confused. I had to manually delete the old file.
**Lesson**: Always tell Cursor to “delete the original file” explicitly. It won’t do it by default.
## Real Flaws and Workarounds
Cursor is powerful, but I’ve hit three consistent wall:
1. **Hallucinated imports**: Cursor often imports functions that don’t exist. For example, it generated `import { validateEmail } from './utils'` but the function was actually in `./helpers/validation.js`. Always verify imports.
2. **Loses track of project structure**: If your project has 100+ files, Cursor’s context window fills up. I found that after 30 minutes of heavy use, the AI starts suggesting code that references files it can’t see anymore. **Fix**: Restart Cursor every hour to clear the context cache.
3. **Overwrites your code without warning**: In inline edit mode, if you ask for a change and then type something new, Cursor **replaces the entire selection** with your new prompt. I once accidentally replaced a working function with a single comment because I typed “# fix this” instead of hitting Enter. **Fix**: Always press `Escape` to cancel an inline edit before starting a new one.
## Next Step: Try the “Explain Project” Feature
Don’t start with refactoring. Start with Cursor’s **Explain Project** feature. Open a folder with a codebase you know well (like a side project), click the “Explain” button in the Chat panel, and ask: “What does this project do?” Cursor will give you a high-level overview. I did this with an old Rails app I hadn’t touched in years, and Cursor correctly identified the architecture, the database schema, and even the testing framework. It’s a great way to test if Cursor understands your code before you trust it with changes.
Go open your messiest project and ask Cursor to explain it. You’ll either be impressed or horrified—either way, you’ll learn something about your own code.