Three weeks ago I got annoyed. My team had just renewed our GitHub Copilot Business licenses — $19/seat/month, twelve seats, do the math — and one of our senior engineers mentioned he'd quietly switched to Cursor on his personal machine and hadn't touched Copilot in a month. That comment sent me down a rabbit hole.
I spent two weeks using all three tools heavily: GitHub Copilot, Cursor, and Codeium (which has since launched its IDE fork, Windsurf). My stack is TypeScript, React, and Node.js. I work on a small product team — four engineers — building a SaaS app. Not a toy project, not a FAANG monorepo. Just real work, shipping features, dealing with legacy code written by Past Alex who was clearly having a bad week.
Here is what I found.
GitHub Copilot Is the Safe Bet (But "Safe" Isn't Always a Compliment)
Copilot is the incumbent. It's been around since 2021, it's deeply integrated into VS Code and JetBrains, and your company's IT department has almost certainly already approved it. That last point matters more than engineers like to admit — procurement friction is real.
The inline suggestions are genuinely good. After years of improvement and now running on a mix of OpenAI models plus GitHub's own fine-tuning on public repositories, the autocomplete feels fluent for common patterns. When I'm writing a new API route in Express, it often completes the entire handler including the error handling boilerplate. That's useful.
Copilot Chat has improved a lot too. The /fix, /explain, and /tests slash commands inside VS Code work well for scoped questions. I used /tests to generate a Jest test suite for a utility module last week — it got about 70% of the way there, which saved me maybe 20 minutes. Not transformative, but real.
Here is the thing, though: Copilot still feels like a very smart autocomplete, not a collaborator. The agent mode (released in late 2024, improved through 2025) is supposed to change this. In practice, I found it useful for small, well-scoped tasks — "update all these API calls to use the new auth header format" — but it got confused on anything requiring understanding of our project's conventions. It doesn't know that we prefix all our custom hooks with use followed by a capital letter and then the domain. It doesn't know our folder structure decisions. It just reads what's in context.
One thing I noticed: Copilot's workspace indexing is still slower to pick up new files than I'd like. I added a shared utility file, started importing it in a different module, and Copilot kept suggesting the old patterns for a solid 10 minutes. Minor, but annoying when you're in flow.
// Copilot was good at completing patterns it recognized:
// I typed "async function fetchUserOrders(" and it completed this:
async function fetchUserOrders(userId: string): Promise<Order[]> {
const response = await fetch(`/api/users/${userId}/orders`, {
headers: {
Authorization: `Bearer ${getToken()}`,
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`Failed to fetch orders: ${response.statusText}`);
}
return response.json();
}
// Solid. But it didn't know our custom `apiClient` wrapper that handles
// retries and token refresh. It just went with raw fetch.
Practical takeaway: Copilot is excellent for teams where security review and procurement are bottlenecks. It's also the right call if your engineers live inside JetBrains IDEs — Cursor and Codeium's JetBrains support is still catching up. For solo developers or small teams with flexibility, it's probably not the most bang for your buck anymore.
Cursor Is Annoying in the Best Way
I say "annoying" because Cursor made me realize how much time I was wasting on things I thought were fast. That is an uncomfortable feeling.
Cursor is a fork of VS Code, which means your extensions, your keybindings, your themes — all of it carries over. Setup took me about eight minutes (I timed it). The Tab autocomplete is noticeably snappier than Copilot for me, though I'll be honest: I'm not sure if that's model latency or just UI optimization. Your mileage may vary here depending on your network and region.
The feature that changes how you work is Composer (now called Agent in the current release). You describe a multi-file task, and Cursor actually goes and does it — edits files, creates new ones, runs terminal commands if you let it. I used it to refactor a bloated context provider that was doing too many things. I described the problem ("this AuthContext is handling both auth state and user preferences, split them into two separate contexts and update all the import sites"), and it did it. Across nine files. In about 90 seconds.
Was it perfect? No. It missed two import sites and created a naming inconsistency in one of the new files. But catching those two things was faster than doing the whole refactor manually.
The chat sidebar (Cmd+L) is where I spend a lot of time. I can highlight a block of code and ask "why is this re-rendering so much?" and get back a specific, correct answer about missing dependency arrays in my useCallback. Not a generic explanation — an answer that references my actual code.
// I asked Cursor to add optimistic updates to this mutation:
// Original code I highlighted:
async function deleteComment(commentId: string) {
await api.delete(`/comments/${commentId}`);
await refetchComments();
}
// Cursor rewrote it as:
async function deleteComment(commentId: string) {
// Optimistic update: remove from local state immediately
setComments(prev => prev.filter(c => c.id !== commentId));
try {
await api.delete(`/comments/${commentId}`);
} catch (error) {
// Rollback on failure
await refetchComments();
toast.error('Failed to delete comment. Please try again.');
}
}
// It even added the toast notification based on the pattern it saw
// elsewhere in the file. I hadn't asked for that. It was correct.
The gotcha I hit: Cursor's Agent mode can go off-script. I asked it to "add pagination to the users table" and it decided — on its own — to also refactor the table component to use a different state management pattern. The changes weren't wrong, exactly, but they were more than I asked for and they touched code I hadn't reviewed. I've since learned to be more explicit in my prompts and to review the diff carefully before accepting. The "Apply All" button is seductive and dangerous.
The price is $20/month for Pro. If you're billing your time, that pays for itself fast.
Practical takeaway: Cursor is the best tool for developers who write a lot of new code and frequently do mid-size refactors (5-20 files). The Agent mode is genuinely useful, not a demo feature. Just stay in the driver's seat — review every diff before accepting.
Codeium and Windsurf: The Underrated Option
I'll be upfront: I came into this section ready to dismiss Codeium. I'd tried it about a year and a half ago and found the suggestions mediocre. Then they released Windsurf — their own VS Code fork, Cursor's direct competitor — and the reviews caught my attention.
Windsurf's answer to Cursor's Composer is Cascade. The core idea is similar: describe a multi-step task, let the AI figure out the file changes. What Windsurf does differently is the "Flows" concept, where Cascade can pause and ask you clarifying questions mid-task rather than forging ahead with assumptions. In practice, this felt more conservative than Cursor — fewer "surprise" changes, but also a bit slower on complex tasks.
The free tier is real. You get a generous number of completions per month, and the suggestions on common TypeScript/React patterns are competitive with Copilot at this point. If you're a student or working on a side project with actual budget constraints, Windsurf Pro at $15/month is worth looking at seriously.
One thing I noticed: Windsurf's context handling felt slightly better than Copilot's for large files. I have a 900-line component (yes, I know, it's on the list) and Windsurf seemed to maintain awareness of the full file in a way Copilot sometimes loses track of. I don't have a scientific explanation for this — just what I observed.
The extensions compatibility is slightly behind Cursor's since Windsurf is newer. I hit one issue with a custom linter extension that needed a manual workaround. Minor, but worth knowing if you have a complex extension setup.
Honestly, Codeium's standalone extension (for use inside regular VS Code or JetBrains) is also worth a look if you don't want to switch IDEs. It's free for individual use, the suggestions are solid, and there's no vendor lock-in to a custom editor.
Practical takeaway: Windsurf is the best option if you want Cursor-like capabilities without the Cursor price — or if the conservative, ask-before-doing approach to agent tasks matches how you like to work. The free Codeium extension is the best free option, period.
The Thing Nobody Talks About: Context Management
All three tools live and die on how well they understand your project. This is where the real differences show up day-to-day.
Cursor has .cursorrules files, where you can give the AI persistent instructions about your project — your naming conventions, your preferred patterns, what libraries you use. I wrote about 40 lines of project-specific rules and the difference was immediate. Cursor stopped suggesting class components in my React codebase. It stopped using any in TypeScript. It started following our error handling conventions.
Copilot has a similar feature now (.github/copilot-instructions.md), added in the last year. It works, but I found it less reliable than Cursor's implementation — the instructions seemed to "fade" on longer conversations.
Windsurf has its own version (.windsurfrules). Comparable to Cursor's in my experience, though I've had less time to test the edges.
I'm not 100% sure this scales beyond small-to-medium projects — I'd be curious how these tools handle a monorepo with 50+ packages and complex inter-module dependencies. In our codebase (~80k lines), all three tools can lose track of architecture in ways that produce suggestions that are locally correct but globally wrong.
What I'd Actually Use (And Pay For)
If I'm paying out of my own pocket: Cursor. The Agent/Composer feature has saved me enough time in two weeks to justify $20/month several times over. The Tab autocomplete is fast, the chat context is good, and .cursorrules makes it feel like a tool that knows my codebase.
If my company is paying and procurement is a factor: GitHub Copilot Business. The JetBrains support is better, the security review story is simpler, and the integration with GitHub itself — pull request summaries, code review assistance — is genuinely useful at the team level.
If I'm on a budget or working on a side project: Windsurf free tier or the Codeium extension. Don't sleep on these. A year ago I would have said the free options weren't competitive. That's no longer true.
The honest version: these tools are all good now. The gap between first and third place is smaller than the gap between having any of them and having none. If you're still writing code without AI assistance in 2026, that's the more significant problem to solve.
Pick one, learn it deeply, configure it for your project, and use it consistently for a month. The .cursorrules / copilot-instructions file alone will make whatever tool you choose significantly better. That's where the real productivity gain is — not in the default out-of-the-box experience, but in the version of these tools you build over time.
Top comments (0)