요약하자면 다음과 같습니다: 12,000행(LOC) 규모의 Next.js 15 저장소에서, Cursor 2.0 Composer는 4가지 리팩터링 작업을 실제 시간 기준으로 21분 40초 만에 완료했습니다. /agents 기능을 사용한 Claude Code는 동일한 4가지 작업을 34분 55초 만에 완료했습니다. 하지만 Claude Code의 diff(차이점)는 4번 중 3번이나 첫 시도에 CI(지속적 통합)를 통과했습니다. Cursor는 단 한 번 통과했습니다. 만약 당신의 병목 현상이 _타이핑 시간_이라면 Cursor가 승리합니다. 하지만 병목 현상이 _리뷰 시간_이라면 그 결과는 빠르게 뒤집힙니다.
저는 지난 두 달 동안 두 도구를 실제 업무에 사용해 왔습니다. 저는 항상 같은 고민에 빠지곤 했습니다. 작업이 "랜딩 페이지를 분위기 있게 코딩하는 것(vibe-code)"이 아니라 "실제 존재하는 무언가의 형태를 바꾸는 것"일 때, 실제로 어떤 도구가 구원자가 되는가 하는 점 말입니다. 그래서 저는 스톱워치를 들고 앉았습니다.
Same repo, four refactor tasks, two tools, side-by-side timing and CI-pass results
이 결과가 당신에게도 적용될지 판단할 수 있도록 한 설정값
- 저장소(Repo): 내부 Next.js 15.4 앱, 약 12,000 LOC TypeScript, App Router, Drizzle ORM, tRPC, Tailwind, Vitest + Playwright.
- 두 도구 모두: 2026-07 기준 최신 버전. Composer 2.5를 포함한 Cursor 3.3, 그리고 Sonnet 4.6을 메인 모델로, Haiku 4.5를 서브 에이전트(subagent) 모델로 사용하는 Claude Code CLI.
- 방법: 깨끗한 git 브랜치에서 각 작업에 대해 동일한 프롬프트를 각 도구에 제공했습니다. 이전 채팅 컨텍스트는 없었으며, Cursor 측의
AGENTS.md와 Claude 측의 매칭되는 CLAUDE.md 외에는 튜닝된 시스템 프롬프트도 없었습니다. 프롬프트 전송부터 "에이전트 중단"까지의 시간을 측정했습니다. 그 후 pnpm typecheck && pnpm test && pnpm build를 실행하여 통과 여부를 확인했습니다.
장난감 같은 문제도 아니고, 그렇다고 불가능한 목표(moonshots)도 아닌, 엄선된 4가지 작업은 다음과 같습니다:
- 타입이 지정되지 않은 유틸리티 모듈에 엄격한 타입 (strict types) 추가. 약 180줄, 곳곳에
any 사용됨, 12곳에서 호출됨.
- 컴포넌트 테스트 스위트를 "shallow render + snapshot" 방식에서 "user-event + role queries" 방식으로 전환. 8개의 테스트 파일.
- Drizzle 쿼리의 N+1 문제 수정. 중첩된
.map()이 행마다 개별 선택(select)을 수행하고 있어, groupBy를 포함한 단일 조인(join)으로 변경 필요.
- 한 라우트의 스타일링을 Tailwind 유틸리티 범벅(utility soup)에서 CSS Modules로 마이그레이션. 반응형 동작을 유지하고 다크 모드(dark mode) 회귀가 발생하지 않도록 할 것.
실제 수치
| 작업 | Cursor 2.0 Composer | Claude Code /agents | 첫 시도 CI 통과 여부 |
|---|
| 1. 엄격한 타입 (Strict types) | 3분 10초 | 6분 05초 | Cursor: 실패. Claude: 통과. |
| ... | | | |
실제 소요 시간(wall-clock) 차이는 Cursor가 60% 유리합니다. 하지만 CI 통과 여부의 차이는 Claude가 200% 유리합니다. 만약 이 중 하나에만 가중치를 둔다면, 팀에 맞지 않는 도구를 선택하게 될 것입니다. 제가 이 비교의 첫 달 동안 Cursor가 이기고 있다고 조용히 확신했다가, Cursor가 만든 디프(diff)를 다시 작성하는 데 낭비한 시간을 모두 합산하고 나서야 깨달은 사실입니다.
시간 차이가 발생하는 실제 원인
Cursor 2.0 Composer는 320k-토큰 컨텍스트(context)를 가진 하나의 긴 에이전트 루프(agentic loop)를 실행합니다. 따라서 수정이 필요한 저장소(repo)의 전체 슬라이스를 보유하고 있으며, 파일을 다시 읽기 위해 멈추는 경우가 드뭅니다. 이것이 속도 우위의 핵심입니다. 바로 타이핑을 하는 것이죠.
Claude Code의 /agents 모델은 다른 방식을 취합니다. 리드 에이전트(lead agent)가 계획을 세운 다음, 독립적이라고 판단되는 청크(chunk)들을 위해 서브 에이전트(subagents)를 생성하며, 각 서브 에이전트는 자신만의 컨텍스트 윈도우(context window)를 가집니다. 서브 에이전트들은 병렬로 실행될 수 있지만, '계획 후 확산(plan-then-fanout)' 단계 자체에 오버헤드가 발생하며, 리드 에이전트가 결과를 확정(commit)하기 전에 결과를 다시 읽습니다. 제가 수행한 4가지 작업에서 발생한 추가적인 약 13분은 바로 이 과정에서 소요되었습니다. 작업 2(테스트 재작성) 하나만 보더라도, Claude는 파일에 손을 대기 전 계획을 세우는 데 90초를 사용했습니다. 반면 Cursor의 첫 번째 edit_file 호출은 4초 만에 이루어졌습니다.
하나의 머리로 처리할 수 있는 모든 작업에서는 Cursor의 타이핑 속도가 우세합니다. 하지만 작업이 세 개 또는 네 개의 개별적인 부분으로 나뉘는 순간, 분산(fan-out) 방식이 빛을 발하며 Claude가 격차를 좁힙니다. 제 작업들은 단일 범용 에이전트(generalist agent) 크기로 측정되었기 때문에 병렬 처리의 상한선 자체가 낮았습니다. 만약 '이 22개 파일에 대한 테스트 추가하기' 또는 '이 기능을 네 가지 로케일로 포팅하기'와 같은 작업을 하신다면, 사용 경험은 빠르게 달라질 것입니다.
실제로 diff 품질 격차가 발생하는 지점
네 번의 실패한 CI(Continuous Integration) 실행 전반에서 제가 발견한 패턴은 동일했습니다. Cursor는 빠르게 움직이며, 다른 곳에 임포트된 형태와 자신이 생성하는 _형태_가 일치하는지 확인하기도 전에 파일을 완성해 버립니다.
Task 1, 엄격한 타입: Cursor는 type Foo = { … }를 추가했는데, 이는 거의 맞았지만 유틸리티 모듈(util module)에서 내보내기(exporting) 하는 대신 호출 지점(call site)에서 타입을 인라인(inline) 처리했습니다. 따라서 세 개의 소비자(consumer)가 여전히 any 타입으로 지정되었습니다. 타입 검사(Typecheck)는 오직 유틸리티 파일에서만 통과했습니다. Claude는 느렸지만, 먼저 호출자를 검색한 다음, 내보내기된 타입을 작성하고, 임포트를 업데이트한 다음, 유틸리티 코드를 작성했습니다.
Task 2, 테스트 재작성: Cursor는 스냅샷(snapshot)을 getByRole('button') 쿼리로 대체했는데, 이는 개별적으로는 정확했지만 두 개의 컴포넌트가 각각 버튼 두 개를 렌더링하기 때문에 실패했습니다. 이 사실을 알기까지 테스트가 실패해야 했습니다. Claude는 각 테스트에 대해 컴포넌트의 JSX를 실제로 읽어들이는 서브 에이전트를 실행한 후 쿼리를 작성했습니다.
Task 4, 둘 다 실패: 다른 세 가지 작업을 믿고 싶어서 솔직하게 포함하는 작업입니다. CSS Modules 마이그레이션 과정에서 두 도구 모두 하나의 그리드(grid)에 대한 sm: 브레이크포인트(breakpoint)를 놓쳤습니다. 두 도구 모두 페이지를 실행해 볼 방법이 없었기 때문에, 단순히 토큰만 변환했습니다. 둘 다 이를 포착하려면 브라우저 서브 에이전트(또는 저)가 필요했을 것입니다. 이것은 AI 에이전트들이 2026년에도 여전히 숙제 같은 작업을 맡기는 유형의 작업입니다.
두 줄 요약: Cursor의 루프 방식은 작업이
내가 실제로 내린 결정
나는 둘 다 유지합니다. 서로 다른 작업에 사용합니다.
Cursor 2.0 Composer는 다음과 같은 경우에 사용합니다:
- 코드의 형태가 아직 존재하지 않는 그린필드 (Greenfield) 기능 개발.
- 어차피 내가 _검토 단계 (review pass)_를 거쳐야 하는 모든 작업. 느리고 정확한 결과물보다는, 내가 논쟁하며 수정할 수 있는 빠르고 (알려진 방식으로) 틀린 차이점 (diff)을 받는 것이 더 낫습니다.
- 단일 파일 수술 — 컴포넌트 추출, 훅 (hook) 이름 변경, switch 문을 룩업 테이블 (lookup table)로 변환 등.
Claude Code /agents는 다음과 같은 경우에 사용합니다:
- 차이점 (diff)이
pnpm typecheck를 통과해야 하며, 내가 일일이 지켜보고 싶지 않은 파일 간 리팩터링 (cross-file refactors).
- 실제 테스트 매트릭스 (test matrix)가 존재하는 모든 작업. 파일당 서브 에이전트 (subagent-per-file) 패턴은 내가 수동으로 작업을 분할하는 방식과 진정으로 일치합니다.
- 마이그레이션 (Migrations). 작업 내용에 "모든 것을 일관되게 유지하라"라는 문구가 포함될 때마다, 서브 에이전트들은 제값을 합니다.
만약 Next.js 저장소에서 단 하나만 가져야 한다면, 나는 Claude Code를 선택할 것입니다. 왜냐하면 나는 10분을 더 기다리는 것보다 깨진 차이점 (diff)을 다시 쓰는 것을 더 싫어하기 때문입니다. 하지만 이것은 _취향_의 문제입니다. PR 리뷰 비용은 높고 타이핑 비용은 낮은 팀이라면 결정을 뒤집어야 합니다. 내일 데모를 출시해야 하는 1인 개발자라면 절대로 Claude Code를 선택하여 오후 시간의 60%를 날려버려서는 안 됩니다.
만약 이것이 당신의 저장소라면 내가 측정할 것들
내가 수행한 네 가지 작업을 정석으로 받아들이지는 마세요. 방법론을 참고하세요:
- 실제 작업이 대기 중인 브랜치를 고정(Freeze)합니다.
- 수동으로 했을 때 각각 5~15분 정도 걸리는 네 가지 작업을 선정합니다.
- 깨끗한 상태에서 스톱워치를 켜고 두 도구를 모두 실행합니다.
- 두 가지를 별도로 측정합니다: 에이전트 중단 시점까지의 시간 (time-to-agent-stop), 그리고 첫 시도에서의 CI 통과 여부 (CI pass on first try).
- 또한 **직접 다시 써야 했던 차이점의 줄 수 (lines-of-diff-you-had-to-rewrite)**를 계산하세요. 이는 두 도구 모두 보고하지 않는 숨겨진 비용입니다.
두 번째와 다섯 번째 수치가 당신의 생각을 바꿀 것입니다. 실제 경과 시간 (Wall-clock)은 화려해 보이는 지표이지만, 재작성 비용 (rewrite-cost)은 PR이 여전히 열려 있는 다음 주 수요일 오후에 당신이 실감하게 될 비용입니다.
Claude Code 측면을 더 깊이 파고들고자 하는 분들에게, 서브에이전트 (subagents)의 멘탈 모델(mental model)과 /agents 플래너가 어떻게 작업을 분산(fan out)할지 결정하는 방식은 일주일 안에 그 읽는 시간이 아깝지 않다고 느껴질 만한 요소 중 하나입니다. 이에 대해 제가 Kindle에 작성한 글을 아래에 첨부했습니다.
Claude Code의 전체적인 멘탈 모델 — 서브에이전트 (subagents), 훅 (hooks), 스킬 (skills), 그리고 이 글에서 다룰 공간이 부족했던 /agents의 구성 요소들 — 에 대해 알고 싶다면, 제가 책으로 정리해 두었습니다:
Claude Code Mastery