I used all three tools in production. Ran them across real products. Spent over $60/month at my peak. The answer is clear now.
To Cursor users: this might make you switch.
The Basics: 3 Tools at a Glance (as of May 2026)
| Claude Code | Cursor | Aider | |
|---|---|---|---|
| Price | $20/mo (Max) or API pay-as-you-go | $20/mo (Pro) | Free (API costs separate) |
| Interface | Terminal (CLI) | VSCode-based IDE | Terminal (CLI) |
| Model | Claude 3.5/3.7/4.x Sonnet | GPT-4o / Claude 3.5 | GPT/Claude (selectable) |
| Context | Whole project | Per-file + @mentions | git diff + /add |
| Autonomy | High (agentic) | Medium (suggestion-based) | Medium (commit-unit) |
I'm running 4 SaaS products solo in production right now. I've used all three tools across every part of that process. This is that comparison.
Claude Code: The Reality
How It Works
The core of Claude Code is CLAUDE.md — a file where you feed the project context. Once it's there, context carries over across sessions without any extra work.
# Project: Real Estate Video SaaS
## Stack
- Next.js 15 (App Router)
- Supabase (PostgreSQL + Auth + Storage)
- Stripe (Subscription)
- Vercel (Deploy)
## DB Tables
users / properties / videos / subscriptions / tenants
## Coding Rules
- Use Server Actions (API routes for webhooks only)
- Errors: console.error + send to Sentry
- env: centralized in lib/env.ts
- Types: generated from Database type in /types/database.ts
Say "add Stripe webhook handling" and it reads CLAUDE.md, matches your existing patterns, and outputs this:
// app/api/webhooks/stripe/route.ts
import { NextRequest, NextResponse } from 'next/server'
import Stripe from 'stripe'
import { stripe } from '@/lib/stripe'
import { createClient } from '@/lib/supabase/server'
export async function POST(req: NextRequest) {
const body = await req.text()
const sig = req.headers.get('stripe-signature')!
let event: Stripe.Event
try {
event = stripe.webhooks.constructEvent(
body,
sig,
process.env.STRIPE_WEBHOOK_SECRET!
)
} catch (err) {
return NextResponse.json({ error: 'Webhook Error' }, { status: 400 })
}
const supabase = await createClient()
switch (event.type) {
case 'customer.subscription.created':
case 'customer.subscription.updated': {
const sub = event.data.object as Stripe.Subscription
await supabase
.from('subscriptions')
.upsert({
stripe_subscription_id: sub.id,
stripe_customer_id: sub.customer as string,
status: sub.status,
current_period_end: new Date(sub.current_period_end * 1000).toISOString()
})
break
}
case 'invoice.payment_failed': {
const invoice = event.data.object as Stripe.Invoice
await supabase
.from('subscriptions')
.update({ status: 'past_due' })
.eq('stripe_customer_id', invoice.customer as string)
break
}
}
return NextResponse.json({ received: true })
}
It picked up the lib/supabase/server import style, the subscriptions column names — all from reading the existing project files. I specified nothing.
What's Not Great
Cost is unpredictable. The Max plan is $20/month unlimited, but on API billing I've hit $10+ in a single day. Also the "confidently writes outdated APIs" problem persists. It sometimes doesn't know the latest API for newer libraries — always review before shipping.
Best for: implementing new features end-to-end, scaffolding from scratch, large refactors
Cursor: The Reality
Autocomplete and Chat Are Solid
Cursor's inline completion was the most comfortable of the three. The feeling of Tab-predicting the next line is real.
For small fixes, Cursor is fast:
// Original (loose typing)
const { data } = await supabase.from('users').select('*').eq('id', userId).single()
// Just say "tighten the types" and Cursor outputs:
const { data, error } = await supabase
.from('users')
.select('id, email, name, plan, created_at')
.eq('id', userId)
.single<Pick<Database['public']['Tables']['users']['Row'],
'id' | 'email' | 'name' | 'plan' | 'created_at'
>>()
if (error) throw error
Single-file edits like this feel noticeably snappier in Cursor.
Breaks Down Across Multiple Files
It's weak at grasping the full project. "Add stripe_customer_id to users table and use it in the webhook" goes like this:
# Real Cursor exchange (close approximation)
You: add stripe_customer_id to users and use it in the webhook
Cursor: Which files should I reference? Please @-mention them.
You: @lib/stripe @types/database.ts @app/api/webhooks/stripe
Cursor: Where should the migration file go?
You: supabase/migrations/
Cursor: (creates migration) Any other files that need changes?
You: ...end up doing it yourself
When I become the context-feeding assistant for large tasks, that alone costs me 20-30 minutes.
Best for: partial edits to existing code, small bug fixes, tab-completion-driven daily work
Aider: The Reality
Git Integration Is Genuinely Good
Auto-commits per change is legitimately useful. "I can roll back to exactly here" becomes concrete.
# Aider session example
$ aider --model claude-3-5-sonnet-20241022
/add app/api/webhooks/stripe/route.ts lib/stripe.ts types/database.ts
# Prompt:
# Add stripe_customer_id to users and write an upsert in the webhook
# After changes, auto-commits:
# Commit 9f3c1a2 feat: add stripe_customer_id to users and webhook upsert
And it's free (just API costs). If you're trying AI coding for the first time, Aider has the lowest barrier to entry.
Low Autonomy Is the Ceiling
When a complex task hits a wall, Aider stops. Claude Code debugs the error and retries on its own. Aider asks "what do you want to do?" Running 4 products solo, this difference shows up every single day.
Also, context resets between sessions. You restart every time by re-adding files with /add.
Best for: one-off fix tasks, first steps into AI-assisted coding
Landmines I Actually Hit (from real experience)
Only listing what I personally stepped on.
Claude Code landmines
- Tried to hardcode .env.local values by guessing them — secret almost ended up in git
- Reported "ran tests and confirmed" when tests hadn't actually run (happened twice)
- Doesn't know the latest API for some newer libraries — need to specify the version and say "check the official README"
Cursor landmines
- Ignores .cursorrules mid-task during long Composer sessions
- After applying multi-file Composer changes, stale code sometimes remained
- Tab completion misread a long comment and deleted it along with surrounding code
Aider landmines
- Sometimes edits files you never added via /add — unintended changes end up in git
- Without --model specified, falls back to an old default model
- Long sessions cause it to forget instructions from earlier in the conversation
Why I Went All-In on Claude Code
Three reasons.
1. "Just handle it" works
My style is: decide the high-level spec, delegate the implementation. Claude Code takes that. Cursor asks "which part do you want to fix?" Aider asks "which files should I add?" Every interruption breaks my focus.
2. Context management disappears when running 4 products
With CLAUDE.md in each project, context carries over across sessions. With Cursor, every project switch meant re-feeding context via @filename. Ten times a day, that adds up.
3. The cost math worked out
| Tool | Estimated monthly cost |
|---|---|
| Claude Code Max | $20 + API $15-30 |
| Cursor Pro | $20 |
| Aider | Free + API $10-20 |
Claude Code is the most expensive. But thinking in hourly rate terms — if 1 hour of work compresses to 20 minutes, the extra $30/month is cheap. Higher implementation speed means my own time costs less.
The Verdict: When to Use Which
| Scenario | Pick |
|---|---|
| Implementing a feature from scratch | Claude Code |
| Partial edits to existing code | Cursor |
| Trying AI coding for the first time | Aider |
| Zero budget | Aider |
| Running multiple production products solo | Claude Code |
| Team with existing VSCode workflow | Cursor |
There are people for whom Cursor is the right answer. If you're on a team and maintaining an existing VSCode setup, Cursor fits naturally. Under my conditions, Claude Code was the only call.
The question isn't "which is the best" — it's "which fits your use case."
I say this as someone who used Cursor for 6 months. No regrets switching. But I don't think everyone should. Try one week and you'll have your own answer.
Originally posted on note (Japanese): https://note.com/mintototo1/n/na615d239961f
Top comments (0)