바이브코딩으로 1시간 만에 프로토타입을 만들었지만, 프로덕션 수준으로 배포하고 다듬는 데는 100시간이 걸렸다. UI/UX, 프롬프트 튜닝, 인프라, 온체인 민팅, 엣지 케이스가 ‘남은 10%’의 대부분이었다.
지난달, 나는 바이브코딩에 약 100시간을 썼다.
이제는 “30분 만에 앱을 바이브코딩했다”고 말하는 사람들은, 이미 존재하는 프로젝트의 단순한 복제품을 만들었거나, 버그 투성이의 쓰레기를 만들어냈거나, 아니면 그냥 참여(engagement)만 농사짓는 거라고 거의 확신한다.
그리고 이건 내가 AI 회의론자라서가 아니다. 오히려 정반대다.
내 이전 스타트업에서는 2023년 말부터 AI로 코딩을 시작했다. 그때는 아직 ‘바이브 코딩’이라는 이름조차 없었다.
그건 논란이 있었다. 당시 LLM은 그리 좋지 않았고 우리는 오픈소스 프로젝트였기 때문에, 사람들이 우리의 스파게티 코드베이스에 기여하는 걸 꺼리게 만들었다.
하지만 Tim은 AI의 잠재력을 일찍 알아봤고, 그는 gpt-cli로 gpt4-preview를 썼다. 나는 말 그대로 내 코드를 ChatGPT 앱에 붙여넣었다. 우리는 간단한 일(예: 앱 레이아웃에 새 콘텐츠 끼워 넣기)에 썼고, AI가 좋아지면서 점점 더 복잡한 기능도 그렇게 출시하기 시작했다.

이후 우리는 Cursor와 Claude Code로 넘어갔고, 그런 초기의 AI 수용이 우리에게 우위를 줬다. 덕분에 나는 AI가 코딩 초능력이 될 수 있다고 믿게 됐다.
하지만 — 2026년 3월 기준 — 거기에도 한계는 있다.
그리고 나는 그 한계를 시험해보고 싶었다.
Kiwi에서 바이브코딩을 했던 것 외에도, 나는 “진짜” 코딩 경험도 조금은 있었다. 100일 파이썬 코스를 했고, JS 날씨 앱을 만들었고, Cryptozombies 스마트 컨트랙트를 몇 개 배포했고… 등등. 그리고 물론 Claude로 로컬 앱도 꽤 많이 바이브코딩했다.

이제 더는 이런 사람이 되고 싶지 않았다.
이제는 앱을 대중에게 출시하는 전체 과정을 혼자서 끝까지 해볼 때였다. 그게 나를 더 나은 PM으로 만들어줄 거라고 생각했다.
주된 목표가 학습이었기 때문에, 나는 “제대로 된 방식”으로 하기로 했다. 즉, 인프라 부분이 가려져 있는 Replit이나 Lovable에 의존하고 싶지 않았다. 그 복잡함을 내가 직접 다루고 싶었다.
과정을 좀 더 즐겁게 만들기 위해, 재미있는 무언가의 SLC를 만들기로 했다.

Jason Cohen의 말대로 SLC는 MVP가 원래 의도했던 것이었다
테이블 위에 올려둔 몇 가지 아이디어 중에서, 나는 Cryptosaurus를 골랐다. 앱은 단순하다 — 공룡을 고르면, 앱이 내 pfp를 받아서 내 pfp 스타일로 꾸며진 공룡을 만들어준다. 단순하고, Lovable하고, Complete하다.

앱의 핵심 아이디어.
내 머릿속에는 하이레벨 비전이 있었고, “교과서대로” 만드는 법도 알고 있었다. 하지만 이렇게 생각했다. “좋아, 유행을 받아들여서 트위터 인플루언서들이 말하듯 ‘그냥 만들어보자’.”
그런데 이 “그냥 만들기”는 내가 예상했던 것보다 훨씬 오래 걸렸다.
나는 ChatGPT(5.2 Thinking Extended)에 아이디어를 설명하는 것부터 시작했다. 한동안 논의하면서 범위를 좁혔고, 시작할 준비가 됐다. 그 스코프를 Opus 4.5에 보내고 Plan Mode를 켠 다음 결과를 기다렸다.
그 사이에 Gemini API 키를 받아서 .env에 추가했고… 짠! 첫 한 시간 만에 동작하는 프로토타입이 나왔다.
와, 그럼 이제 곧 공개하겠지?
아니다.
나는 기본 보일러플레이트 디자인이 마음에 들지 않았다.
그래서 Coolors로 마음에 드는 팔레트를 찾아봤다. 뭔가를 골라 UI에 적용해보고, 색을 바꾸고. 반복. 몇 번 돌고 나서야 색이 맞아졌다.
그러고 나서 Claude가 UI와 UX를 과하게 복잡하게 만들었다는 걸 알아챘다. 그래서 단순화하기 시작했다. 내가 Figma를 썼다면 10분 만에 10가지 변형을 만들고 결과를 픽셀 단위로 완벽하게 통제했을 거다. 하지만 나는 “그냥 만들기”를 하고 싶었잖아?
그래서 LLM에게 새 UI를 만들라고 했다. 마음에 안 들어서 Claude에게 다시 만들라고 했다. 중요한 디테일이 빠져서 다시 프롬프트를 써야 했다. 그러다 UI를 더 단순화할 수 있겠다는 걸 깨닫고 아예 완전히 다시 만들라고 했다.
그러다 프론트엔드를 깨는 이상한 컨테이너가 생겼다. 그러다 모바일에서 뭔가가 제대로 렌더링되지 않았다. 그러다 원치 않는 이상한 아웃라인이 생겼다. 등등. 매 반복은 몇 분씩 걸렸다: 내 프롬프트, LLM이 구현, 마음에 드는지 확인, 다시 프롬프트.
시간은 계속 갔다. 내가 “그냥 Figma를 썼다면” UI는 10배는 더 빨리 준비했을 거다. 하지만 뭐, “그냥 만들자.”
그리고 이건 빙산의 일각이었다.
Cryptosaurus의 주요 “제품”은 공룡 이미지였기 때문에, 이미지가 좋아 보이도록 보장해야 했다. 내 pfp로는 좋아 보였지만 다른 사람의 pfp로도 그럴까?
나는 몇 가지 엣지 케이스 pfp를 골라 출력이 잘 나오는지 확인했다. 그런데 안 됐다. 어떤 건 프레임이 바뀌고, 어떤 건 배경에 랜덤한 프롬프트 텍스트가 렌더링되고, 어떤 건 사진 자체가 완전히 바뀌어 버렸다.

예상대로 동작하지 않았던 출력 예시
Gemini, Codex(막 출시됨), Claude(4.6이 막 나옴)와 함께 이 문제를 논의하기 시작했다. 프롬프트를 바꾸고, 이미지를 올리고, 새 이미지가 생성될 때까지 기다린다. 이제 배경이 빠졌다. 이제 머리 장식이 사라졌다. 이제 이상한 텍스트가 보이고 수염이 자연스럽지 않다.
나는 이 과정을 최소 200번은 반복했다. 시간은 계속 갔다 — “30분 만에 앱 만들기”는 이미 한참 넘었다.

모든 엣지 케이스를 커버하기 위해, 내 prompt.ts 파일은 274줄이 됐다. 그리고 프롬프트를 Gemini로 보내는 스크립트에도 엣지 케이스를 고치고 나쁜 출력물을 막는 기능들이 들어갔다.
그리고 나는 아직도 localhost를 벗어나지 못했다.
프롬프트를 해결하고 나니, 이제는 밖으로 내보낼 차례였다.
Cloudflare에서 cryptosaurus.app 도메인을 사고, Vercel에 설정했다. 이제 백엔드를 서버에 올릴 시간이었다.
LLM과 좀 더 긴 대화를 한 끝에, 꽤 저렴하고 예전부터 배워보고 싶었던 AWS를 쓰기로 했다. 콘솔을 열고 방대한 AWS 서비스의 바다를 보자, 이건 오버킬이라는 걸 알았다. 하지만 더 단순한 인프라를 쓰는 대신, 끝까지 밀어붙여서 S3와 Lambda를 설정하기로 했다.
몇 번 시도하니 되는 것 같았다. 하지만 아니었다. 뭔가가 깨졌다. 버킷을 공개로 만들지 않았다. 그리고 이제 어떤 .env는 Vercel이나 AWS에 공유되지 않았다. 오케이, 뭐가 문제인지 찾았다. 가자!
곧 AWS CLI를 발견했고, LLM이 대신 설정해줄 수 있다는 사실에 신이 났다.
그런데 도움을 요청하자, 앱이 다시 멈췄다. 조사해보니 Claude가 내가 직접 만든 S3 버킷을 쓰는 대신 새 S3 버킷을 자동으로 만들고 있었다. 오케이, 그건 고쳤다. 하지만 또 다른 “알지 못했던 미지(unknown unknown)”가 내 머리를 쳤다.
수많은 핑퐁 끝에 인프라는 괜찮아졌다. 이제 Farcaster Mini App으로 동작하게 만들어야 했다. FC 사용자들은 pfp를 모으는 걸 좋아했고, 나도 그 네트워크에서 이미 배포(distribution)를 갖고 있었기 때문이다. 그런데… Developer Mode에서는 알림이 동작하지 않아서 앱을 완전히 테스트할 수가 없었다.
오케이, 매니페스트를 추가하고 앱이 공개되지 않도록 noindex를 넣어야 한다. 오케이, 그런데 그러면 사람들이 내 메인 계정에서 뭘 하는지 볼 수도 있으니 테스트용으로 다른 계정이 필요하다. 오케이, 설정하자.
이제 모바일 UI는 브라우저에서는 제대로 동작하는 것 같지만, 미니앱 UI에서는 뭔가가 깨진다. 또 프론트엔드 수정. 이번엔 내가 더 똑똑해져서 브라우저에서 코드를 직접 검사하고, 컨테이너 스크린샷을 LLM에게 보냈다.
오케이 이제 공룡 NFT를 민팅하자. 아, 그런데 이 지갑들에서는 테스트넷이 동작하지 않는다. Base Mainnet에 컨트랙트를 재배포. 이제 모든 곳의 .env를 바꿔야 한다. 에휴…
오케이. 했다. 다 된다.
그러다 생각했다… 오케이, 내가 “프로덕션급 방식”을 배우려고 한다면, CLI로 내 스마트 컨트랙트를 호출하지 못하게 보호도 해야 한다.
그래서 이제는 내 앱만 공룡을 만들 수 있도록 보장해야 했다. 그러려면 스마트 컨트랙트를 바꾸고, 사용자 대신 NFT를 민팅해줄 별도의 이더리움 주소로 onlyMinter를 설정해야 했다.
또 private key가 유출될 경우를 대비해 Owner와 같은 주소로 두고 싶지 않았으므로, 컨트랙트 오너가 되는 Safe를 설정해야 했다. Safe는 문제가 생기면 onlyMinter를 바꿀 수 있어야 했다.

사용자 관점에서는 단순했지만, 내부에서는 할 일이 엄청 많았다.
그리고는 이런 생각이 들었다… 오케이, 만약 100명이 동시에 앱을 쓰고 싶어하면 어떡하지? 감당할 수 있을까? 내 LLM들은 못할 거라고 했다. 그래서 2일 동안 여러 엣지 케이스, 레이트 리밋, 잠재적인 사용자 폭증에 대비하는 것들을 파악했다. 일부 앱은 유료 버전으로도 옮겼다.
긴 체크리스트를 끝내고, 이제 출시할 시간이었다.
앱을 공유하기 2주 전에 프리런치를 했고, Farcaster에서 약 500명이 앱을 ‘설치’했다.
런치 포스트를 공유하고 알림을 보냈더니 사람들이 앱을 열기 시작했다...

Farcaster에서 런칭한 멋진 점 하나는, 한 포스트 안에 이미지와 피드 내 앱 링크를 임베드할 수 있다는 거였다. 사용자가 공룡을 받으면, 바이럴을 만들기 위해 피드에 공유하도록 유도했다.
...그리고 앱이 터졌다. 내가 공들여 만든 바이럴과 함께.
사용자 폭증에 대비하려고 Codex 5.3 Extra High와 Opus 4.6을 써서 앱과 API를 준비했지만, 두 LLM 모두 nonce를 잊었다. 그래서 두 사람이 동시에 공룡을 받으려 하면 결제는 되는데, 이미지 생성과 NFT 민팅을 위한 요청이 API에 도달하지 못했다.
영향 받은 모든 사람에게 환불해주겠다고 말하고, 버그를 고치기 시작했다.
늦은 밤 대부분의 문제가 해결됐고, 결제가 걸려버린 사람들을 찾는 스크립트를 작성했다. 그들에게 돈을 돌려보냈고(‘기다려줘서 고마워요’라는 의미로 추가로 $1 더), DM으로 안내했다. 사람들은 내 빠른 대응에 기분 좋게 놀랐고, 그들 대부분은 어쨌든 공룡을 다시 받기로 했다.
결국 여러 난관에도 불구하고, 많은 사람들이 공룡을 민팅하고 피드에 공유했다:

그리고 앱의 v1은 완성됐다고 말할 수 있었다. 30분보다 훨씬 오래 걸렸지?
이제 잠깐 큰 그림을 보자.
처음에 말했듯이, 나는 1시간 만에 프로토타입을 만들었다.
하지만 vercel215810.buggyslop.com 같은 앱을 내고 싶지 않았고, Replit/Lovable 지름길도 택하고 싶지 않았기 때문에, 프로덕션으로 세팅하는 데 훨씬 더 오래 걸렸다. 이 경우에는 약 100배 더.
만약 코딩 경험이 0인 마조히스트 성향의 사람이 내 “그냥 만들자, 하지만 제대로도 하자” 접근을 따라 하려 한다면, 그 사람은 아마 더 오래 걸릴 거라고 상상한다.
가장 시간을 많이 잡아먹은 요소 중 하나는 UX, UI, 그리고 최종 결과물(공룡 출력물)이었다. 내가 여기에 시간을 투자하기로 한 이유는, 이미 세상에는 다듬어지지 않은 소프트웨어가 충분히 많기 때문이다. AI 이전에도 그랬다. 사람들은 오픈소스 레포를 복제하고 몇 가지 파라미터만 바꿔서 자기 앱을 만들었다.
결국, 이런 날씨 앱을 만들 수도 있다:

아니면 Windy를 만들 수도 있다:

물론 내 앱은 Windy 리그에는 한참 못 미쳤지만, 요지는 알 거다.
좋은 점은 내 주요 목표를 달성했다는 것이다 — (Kiwi에서 그랬던 것처럼) 스태프 레벨 엔지니어와 빡빡하게 함께 일하지 않고도 앱을 만들었고, 그 과정에서 많이 배웠다. 그리고 목표는 학습이었지만 앱 성과도 괜찮았다. 1,000명 이상이 앱을 다운로드했고, 180명 이상이 공룡 하나에 $2를 결제했으며, 앱은 첫 주에 Farcaster Mini App 스토어 TOP3에 올랐다.

모든 사용자와 모든 txs 를 보여주지는 않는데, 일부 사람들은 이 대시보드에 연결되지 않은 예전 앱을 사용했기 때문이다.
물론 우주에 흠집 하나 내지 못한 단순한 앱이다. 하지만 그게 “그냥 SLC를 만들자” 계획의 일부였다. 나중에는 Stage II를 제공하고 싶다. 내 공룡으로 게임을 하고, Farcaster 친구들과 점수를 비교할 수 있게 하는 거다.
시간이 지나면서 나는 이런 도구들을 더 잘 쓰는 법을 배웠다.
서로 방해하지 않도록, 같은 코드베이스에서 동시에 3~4개의 에이전트가 일할 수 있게 LLM 작업 범위를 꼼꼼하게 쪼갰다.
Codex는 Claude에 비해 일을 과하게 복잡하게 만드는 경향이 있다는 걸 알아차려서, agents.md에 항상 LOC 몇 줄로 끝나는 단순하고 우아한 해법을 찾으라고 써뒀다.
에이전트가 30분 동안 계획을 구현하기 전에, LLM에게 플로우차트를 만들게 하고 그걸 반복해서 다듬는 등 아키텍처에 더 많은 시간을 썼다.
그리고 나중에는 이 “그냥 만들기” 철학을 조금 버리고, LLM을 기다리는 대신 Figma로 디자인을 다듬어서 전체 과정이 덜 답답해졌다.
나는 이런 것들과 더 많은 작은 교훈들을 Obsidian에 적어두었고, 기억하기 위해 종종 프롬프트에 그대로 붙여넣기도 했다.
내 경우 바이브코딩은 “30분 만에 앱 만들기”라는 과장에는 못 미쳤지만, 그래도 10~100배의 속도 향상이었다. Replit이나 Lovable을 썼다면 가속은 더 극적이었을 것이다.
하지만 경험 자체는 달랐다.
손으로 코딩하던 때는 즐거운 창작 플로우에 들어갔다. 이제 나는 디지털 직원들에게 일을 지시하는 매니저가 됐고, 그들이 내가 원한 걸 전달하지 못하면 짜증이 난다. 하지만… 여전히 그럴 가치가 있다. 이제는 문법 고치기 대신 무언가를 만드는 데 집중할 수 있기 때문이다.
그리고 엔지니어링 경험은 여전히 중요하다. 특히 디테일을 제대로 잡고 싶을 때.
Brave가 이상한 색을 보여주면서 내 라이트 테마를 덮어써버린 순간이 있었다. 앱에서 그걸 끄고 싶어서 LLM 3개로 해결을 시도했다. 한 시간 후에도 아무것도 바뀌지 않았다. 시니어 디자인 엔지니어인 친구에게 도움을 요청했더니, 코드 한 줄로 고쳤다.
비슷한 문제가 많았다. 경험 많은 엔지니어가 옆에 있었다면 10배는 더 빨리 풀 수 있었을 문제들이다. 그래서 LLM에는 아직 한계가 있으니, 시니어 개발자 친구들에게 도움을 요청하는 걸 강력 추천한다.
이번 경험은 Tom Cargill의 시대를 초월한 명언을 떠올리게 했다:
“코드의 첫 90%가 개발 시간의 첫 90%를 차지한다. 남은 10%의 코드가 나머지 90%의 개발 시간을 차지한다.”
AI 덕분에 첫 90%를 만들어 내는 건 더 쉬워졌다. 즉, 남은 10%에 더 많은 시간을 쓸 수 있고, 이는 장인정신(craftsmanship)과 사용자를 행복하게 만드는 방법을 찾아가는 데 더 많은 시간을 쓸 수 있다는 뜻이다.
“남은 10%”가, 대충 만든 것과 사람들이 즐기는 것의 차이다.

앱을 Lovable하게 만드는 게 좋은 이유 중 하나.
바이브코딩은 코딩에서 지루한 부분을 덜어내고 장인정신을 위한 공간을 더 만들어 주기 때문에, 우리는 결국 더 멋진 디지털 경험을 더 많이 만들게 될 거라고 생각한다. 그리고 그런 멋진 경험을 만들 수 있는 능력이야말로 많은 사람들을 기술 업계로 끌어들였던 이유다.
그래서 결국, 에이전트들이 인간보다 더 나은 PM이 되기 전까지는 제품 만들기는 즐거워야 한다.
PS: Cryptosaurus를 보고 싶다면 이 링크를 클릭 하면 Farcaster 계정에서 미니앱이 실행될 거다. 공룡을 민팅하면, 곧(아마도) 나올 앱의 Stage 2에서 그 공룡을 사용할 수 있게 될 거다.
PS2: 진행 중에 프로팁을 공유해준 Pugson, Kris Kaczor, Sayangel에게 큰 감사를 전한다.