프로덕트를 Ship한다는 것
"아이디어가 있어요. Claude Code로 만들어볼게요."
이렇게 시작한 사람들 중 90%가 좌절한다. 왜 그럴까?
첫 프로토타입은 2시간 만에 완성된다. Firebase 연동도 Claude Code가 알아서 해준다. 로컬에서 실행하면 웹앱이 완벽하게 작동한다. 이때의 흥분은 말로 표현할 수 없다. "내가 앱을 만들었다!" 하지만 이건 시작일 뿐이다.
배포를 위해 Firebase Hosting 설정을 하는데, 빌드 에러가 난다. TypeScript strict mode가 켜져 있어서 타입 에러 37개가 쏟아진다. 물론 Claude Code가 수정해준다. 다시 빌드하니 이번엔 환경 변수 에러다. .env 파일은 로컬에만 있고 production에는 없다. Firebase Console에서 환경 변수 설정하는 법을 Claude Code에게 물어본다.
드디어 배포 성공! URL을 열어본다. 그런데 로그인이 안 된다. Firebase Auth 도메인 설정을 안 했기 때문이다. Claude Code에게 방법을 물어 Console에서 추가한다. 이번엔 로그인은 되는데 데이터가 안 불러와진다. Firestore 보안 규칙이 test mode로 설정되어 있어서 30일이 지나면 모든 접근이 차단된다. 보안 규칙을 다시 작성한다.
일주일이 지났다. 친구에게 앱을 보여준다. "로딩이 너무 오래 걸려요." 성능 최적화를 해야 한다. "이 버튼 클릭하면 아무 반응이 없어요." 로딩 상태를 추가해야 한다. "에러가 났는데 뭐가 문제인지 모르겠어요." 에러 메시지를 사용자 친화적으로 바꿔야 한다.
한 달이 지났다. 이제야 다른 사람에게 보여줄 수 있는 수준이 되었다. 처음 "2시간 만에 완성"했던 프로토타입과 비교하면, 실제 작업 시간의 90%는 프로토타입 이후에 쏟아부었다.
프로덕트를 실제로 ship하려면 생각보다 훨씬 많은 것들이 필요하다. 그리고 그 "많은 것들"은 대부분 개발 초보자가 존재조차 모르는 것들이다.
프로덕트를 ship하는 과정에서 Claude Code가 도와주는 비율은 영역마다 다르다. 기본 기능 코드 작성은 Claude Code가 90% 도와준다. 명확한 요구사항만 있으면 된다. Git 버전 관리는 95%까지 올라간다. 브랜치 개념만 이해하면 commit, push, pull, merge는 모두 자동으로 처리된다. Firebase 기본 연동은 85% 정도다. 데이터 모델 설계는 직접 해야 하지만 코드는 AI가 작성한다.
하지만 여기서부터 숫자가 떨어지기 시작한다. 에러 핸들링은 Claude Code가 50% 정도 도와준다. "어떤 에러 상황을 고려해야 해?"라고 물어봐야 한다. AI가 먼저 제안하지는 않는다. Firebase 보안 규칙은 70% 정도다. 복잡한 규칙도 만들어주지만 "보안 규칙을 secure하게 작성해줘, role 기반으로"라고 구체적으로 요청해야 한다. 성능 최적화는 60% 정도다. "lighthouse 돌려서 문제점 찾아줘", "이 컴포넌트 렌더링이 느린데 병목 지점 찾아줘"라고 물어보면 찾아준다. 하지만 이런 질문을 할 줄 알아야 한다. UI/UX 폴리싱은 50%다. 디자인 감각과 "이게 이상한데"라는 직관은 여전히 사람의 영역이다.
"버그 가득한 코드"라는 오해
"Claude Code는 버그 가득한 코드만 만들어요." 이런 얘기를 정말 많이 듣는다. 하지만 진실은 조금 다르다. Claude Code는 요청한 것을 정확히 만든다. 문제는 요청하지 않은 것들이다.
두 번째 프로젝트를 만들었다고 해보자. 이번에는 조금 더 복잡한 앱이다. "Firebase 사용하는 Todo 앱 만들어줘." Claude Code가 10분 만에 만들어줬다. Todo 추가, 삭제, 수정 모두 작동한다. Firebase도 연결됐다. 당신은 만족했다.
하지만 친구에게 보냈을 때 문제가 터졌다. "Todo 추가 버튼 눌렀는데 아무 일도 안 일어나", "와이파이 끊겼다가 다시 켜니까 데이터가 다 날아갔어", "화면 빈 칸만 나오는데 이거 정상이야?" 당신은 당황했다. 분명 본인 컴퓨터에서는 완벽하게 작동했는데.
문제는 당신이 "행복한 경로"만 테스트했다는 것이다. 인터넷이 잘 연결되어 있고, Todo가 이미 몇 개 있고, 버튼을 정확히 한 번만 클릭하는 상황. 하지만 실제 사용자는 다르게 행동한다. 인터넷이 끊긴다. 버튼을 여러 번 클릭한다. Todo가 하나도 없는 상태에서 앱을 연다. Claude Code는 당신이 요청한 대로 "기본 기능"만 완벽하게 만들었다. 로딩 상태, 에러 처리, 빈 상태 UI는 요청하지 않았으니 만들지 않았다.
반면 경험 있는 개발자는 처음부터 다르게 접근한다. "Firebase Todo 앱 만들되, optimistic updates로 즉시 반영하고, 로딩/에러/빈 상태 전부 처리하고, 오프라인 큐 구현하고, debounced input으로 과도한 호출 방지해줘." 한 번에 요청한다. 결과는? 테스터들이 아무도 문제를 보고하지 않는다.
차이는 무엇을 요청했느냐다. 초보자는 "앱을 만들어줘"라고 한다. 경험자는 "이런 상황에서 이렇게 동작하는 앱을 만들어줘"라고 한다. 초보자는 기능을 요청한다. 경험자는 사용자 경험을 요청한다. AI는 둘 다 완벽하게 만든다. 하지만 결과물의 완성도는 다르다.
"버그 가득한 코드"가 아니다. "요청하지 않은 edge case가 처리되지 않은 코드"다. 3개월 정도 개발하다 보면 이 차이를 배우게 된다. "버튼을 만들어줘"가 아니라 "버튼을 만들되, 로딩 중에는 disabled, 에러 나면 빨간색으로 흔들리고, 성공하면 체크 아이콘 1초 보여줘"라고 요청하는 법을. 그때부터 당신의 앱도 사람들에게 "이거 진짜 잘 만들었다"는 말을 듣는다.
보이지 않는 장벽들
초보자와 경험자는 같은 AI를 쓰지만, 결과물이 완전히 다르다. 왜일까?
Claude Code로 첫 앱을 만들었다고 해보자. "Todo 앱 만들어줘." 10분 만에 완성. 로컬에서는 완벽했다. 친구에게 링크를 보냈다. 5분 뒤 카톡이 왔다. "야, 버튼 눌러도 아무 반응 없는데? 고장난 거 아니야?"
당신은 당황했다. 본인 화면에서는 잘 되는데? 알고 보니 로딩 시간 1초 동안 버튼에 아무 표시가 없었던 게 문제였다. Claude Code에게 물었다. "버튼 클릭하면 뭔가 표시되게 해줘." 해결됐다. 하지만 다음 문제가 터졌다. 데이터가 안 불러와진다. Firebase 보안 규칙(누가 어떤 데이터에 접근할 수 있는지 정하는 설정)이 test 모드라 30일 후 자동 차단된 것이다.
반면 경험 있는 개발자는 이렇게 요청한다. "Firebase Todo 앱 만들되, optimistic updates(사용자 액션을 즉시 화면에 반영하고 서버 실패시 되돌리기), error boundary(전역 에러 처리 컴포넌트), React Query 캐싱 적용해줘." 15분 만에 완성. 여러 명에게 보냈다. 아무도 불편을 호소하지 않았다.
차이는 AI가 아니다. 질문이다. 경험자는 "로딩 상태", "에러 처리", "캐싱"이라는 개념을 알고 있다. 용어를 외운 게 아니라, "사용자가 클릭 후 1초 대기하면 다시 클릭한다"는 문제 상황을 예측한 것이다. 초보자는 문제가 터질 때마다 배우고, 경험자는 미리 막는다.
이게 AI 시대의 역설이다. 코딩은 AI가 해주지만, 문제를 예측하는 눈은 경험에서 나온다. 명령어를 외울 필요는 없다. 하지만 "보안 규칙이 뭔지", "캐싱이 왜 필요한지", "에러 바운더리가 무엇인지"는 이해해야 한다. 그래야 Claude Code에게 제대로 된 요청을 할 수 있다.
개념만 알면 되는 영역
터미널/Git — 명령어는 외울 필요 없다. Claude Code가 다 작성한다. 파일 시스템, 브랜치 같은 개념만 대충 이해하면 된다. (Claude Code 도움: 90% 이상)
Firebase Console — 클릭은 쉽다. 문제는 개념 이해다. "Auth가 뭐지?", "Firestore가 뭐지?"를 알아야 제대로 쓸 수 있다. (Claude Code 도움: 20%)
데이터 구조 설계 — NoSQL(관계형 테이블 대신 문서 기반 저장) 개념, 쿼리 패턴 이해가 필요하다. "이런 구조로 데이터 모델 설계해줘"라고 물어보면 AI가 잘 만들어주지만, SQL처럼 생각하면 안 된다. (Claude Code 도움: 60%)
보안 규칙 — "보안 규칙 secure하게 작성해줘, role 기반으로"라고 요청하면 복잡한 규칙도 잘 만들어준다. 하지만 이런 요청을 할 줄 알아야 한다. (Claude Code 도움: 70%)
질문 능력이 핵심인 영역
에러 처리 — "API 호출시 어떤 에러를 처리해야 해?"라고 물어보면 알려준다. HTTP, CORS(다른 도메인 간 데이터 교환 규칙), 인증 같은 용어를 알면 더 좋다.
성능 최적화 — "lighthouse(구글의 웹 성능 측정 도구) 돌려서 성능 문제 찾아줘", "이 페이지 로딩이 느린데 병목 지점 찾아줘"라고 하면 찾아준다. 문제는 이런 질문을 할 줄 알아야 한다는 것.
비동기 처리 — "이 코드에서 race condition(여러 작업이 동시에 실행될 때 순서 문제) 가능성 있어?"라고 물어보면 알려준다. 하지만 race condition이 뭔지는 알아야 한다.
3개월 정도 지나면 "로딩 상태 빠졌네"를 보는 눈이 생긴다. 문법을 외운 게 아니라, 문제 상황을 경험하며 배운 것이다. AI 시대의 학습은 이렇다. 코드를 읽지 못해도 되지만, "사용자는 이렇게 행동한다"는 감각은 있어야 한다.
Claude Code는 프로토타입 제작을 혁명적으로 바꿨다. 예전 같으면 2주 걸릴 MVP를 이틀 만에 만든다. 하지만 그 MVP를 실제 사용자 100명이 쓸 수 있는 수준으로 만드는 데는 여전히 시간이 걸린다. 차이는 문제를 미리 보는 눈이 있느냐 없느냐다. 그 눈은 도구가 아니라 경험에서 나온다.
사람이 주도해야 하는 영역
Claude Code가 아무리 발전해도, 다음은 여전히 사람의 판단이 필요하다.
첫째, 시스템 사고다. 한 기능이 전체 시스템에 미치는 영향을 예측하는 능력. AI는 요청한 기능을 완벽하게 구현하지만, 그 기능이 다른 부분에 어떤 영향을 줄지는 예측하지 못한다. "이 API 호출을 추가하면 데이터베이스 부하가 10배 늘어나겠네", "이 상태 변경은 다른 컴포넌트에서 무한 루프를 유발할 수 있어"라는 직관은 여전히 사람의 영역이다. 장애 포인트를 미리 식별하고, 확장성을 고려한 설계 결정을 내리는 것. 이건 경험에서 나온다.
둘째, 프로덕트 감각이다. 사용자가 실제로 원하는 게 뭔지 파악하는 능력. AI는 명확한 요구사항을 완벽하게 구현하지만, 요구사항 자체가 잘못되었는지는 판단하지 못한다. "사용자가 이 기능을 원한다고 했지만, 실제로는 다른 문제를 해결하고 싶은 거구나", "이 복잡한 UI는 아무도 안 쓸 거야, 더 단순하게 만들자"는 통찰. MVP와 nice-to-have를 구분하고, 데이터 기반으로 우선순위를 정하는 것. 이건 사용자에 대한 깊은 이해에서 나온다.
셋째, 비즈니스 맥락 이해다. 이 기능이 왜 필요한가? 개발에 2주가 걸리는데 수익은 얼마나 늘어나는가? 이 코드는 3년 동안 유지보수해야 하는데 비용은 얼마나 드는가? AI는 코드를 작성하지만, ROI를 계산하지는 못한다. "이 기능은 멋지지만 비용 대비 효과가 없어", "지금은 빠르게 만들고 나중에 리팩토링하자", "이건 기술 부채가 너무 커, 지금 제대로 만들자"는 판단. 이건 비즈니스에 대한 이해에서 나온다.
넷째, 트레이드오프 판단이다. 완벽한 해결책은 없다. 모든 결정은 트레이드오프다. 빠른 출시 vs 완벽한 품질. 단순한 구조 vs 확장 가능한 구조. 비용 vs 성능. AI는 두 옵션을 모두 완벽하게 구현하지만, 어느 쪽을 선택해야 하는지는 말해주지 못한다. "지금 단계에서는 빠른 출시가 중요해", "이 부분은 나중에 확장될 거니까 지금 제대로 설계하자"는 결정. 이건 맥락에 대한 깊은 이해에서 나온다.
Claude Code는 지금도 강력하고 앞으로 더 발전할 것이다. Edge case 자동 감지, 성능 문제 자동 진단, 보안 취약점 자동 검출, 프로덕션 체크리스트 자동 실행, 테스트 자동 생성까지. 현재 사람이 해야 하는 많은 것들이 자동화될 것이다. 하지만 Claude Code가 완벽해지는 날이 와도, 무엇을 만들지 결정하는 건 여전히 당신이다.
학습의 새로운 패러다임
가장 큰 변화는 학습 곡선이다. 예전에는 개발을 배우려면 "코딩 문법 → 프레임워크 → 데이터베이스 → 배포" 순서로 6개월 이상 공부해야 했다. 지금은 다르다. 첫날부터 Firebase 연동된 앱을 만든다. Claude Code가 코드를 작성해주기 때문이다.
예전에는 "아래에서 위로" 배웠다. 변수 선언부터 시작해서 함수, 클래스, 프레임워크 순서로 차근차근 올라갔다. 6개월 공부하고 나서야 첫 앱을 만들 수 있었다. 지금은 "위에서 아래로" 배운다. 첫날부터 완성된 앱을 만든다. 그리고 필요할 때마다 "이 코드가 왜 이렇게 작동하지?"라고 물으며 개념을 채워나간다. 프로젝트 중심 학습이 자연스럽게 된다.
이 방식의 장점은 동기부여다. 예전 방식은 "언젠가 쓸모있겠지"라는 믿음으로 지루한 문법을 외웠다. 지금은 "지금 당장 필요해"라는 절박함으로 배운다. 내가 만드는 앱에 로그인 기능이 필요하니까 Firebase Auth를 배운다. 데이터 저장이 필요하니까 Firestore를 배운다. 학습 효율이 완전히 다르다.
하지만 역설적으로 개념 이해는 더 중요해졌다. 코드는 읽을 줄 몰라도 된다. 하지만 "데이터베이스가 뭔지", "API가 뭔지", "인증이 어떻게 작동하는지"는 알아야 한다. 그래야 Claude Code에게 제대로 요청할 수 있다. 문법 대신 개념, 구현 대신 설계가 핵심이 되었다.
하지만 함정도 있다. 개념 없이 복붙만 하면 발전이 없다. Claude Code가 만든 코드를 그냥 쓰기만 하면, 겉보기엔 앱을 만들지만 실제로는 아무것도 배우지 못한다. 핵심은 "왜?"를 계속 묻는 것이다. "이 코드가 왜 필요하지?", "이 방식 대신 다른 방법은 없을까?", "이게 실패하면 어떻게 되지?"
성장 속도가 가장 빠른 시점은 첫 에러를 만났을 때다. 로컬에서는 작동하던 앱이 배포하면 안 된다. 에러 메시지를 읽는다. 구글링한다. Claude Code에게 묻는다. 해결한다. 이 과정에서 환경 변수, 빌드 설정, CORS, 보안 규칙 같은 개념을 배운다. 고통스럽지만 확실하게 배운다.
3개월 차가 되면 변곡점이 온다. 이제 Claude Code에게 뭘 물어야 하는지 안다. 에러가 나도 당황하지 않는다. "아, 이건 인증 토큰 만료 문제구나", "이건 캐싱 때문이네", "이건 타입 에러야" 바로 파악한다. AI가 여전히 코드를 작성하지만, 이제는 내가 감독한다. AI가 도구가 되고, 내가 주인이 된다.