세 달 전, "Zero to One을 시작해보자! 난 할 수 있어"라며 의기양양하게 글을 포스팅하고 작업을 시작했다. 하지만 바로 다음에 쓰는 글이 '왜 망했을까'라는 회고라니. 참 씁쓸한 코미디가 아닐 수 없다.
그럼에도 불구하고 이 회고는 나에게, 그리고 나와 비슷한 길을 걷는 이들에게 너무나도 필요하기에 눈물을 머금고 기록을 남긴다.
note모든 망한 프로젝트의 주제는 'AI를 동반한 영어 일기' 서비스다.
동일한 주제와 기능을 가진 프로젝트를 약 3번 정도 갈아엎는 과정을 거쳤다. 이 포스트는 기술적인 스택의 문제라기보다, 1인 개발자가 프로젝트를 관리하는 과정에서 겪은 시행착오에 대한 기록이다.
1. 첫 번째 실패: 프로덕트가 아닌 '코드'를 사랑했던 시간 (25.05 ~ 25.09)
1.1 이 프로젝트는 어떻게 진행되었나?
첫 번째 실패는 다음과 같은 순서로 진행됐다.
- 무계획의 시작: 처음부터 완성된 전체 프로덕트를 꿈꾸며 노트에 대충 디자인을 슥슥 그렸다.
- 껍데기 구현: 노트에 그린 그림을
shadcn/ui라이브러리와 React를 이용해 화면(View)부터 만들었다. 서버 통신이 필요한 부분은 Mock Data로 대충 때웠다. - 3개월의 시간 낭비: 놀랍게도 이 껍데기를 만드는 데만 3개월이 걸렸다. 대단한 기능을 만든 것도 아니었다.
초기에 만들었던 글 쓰기 페이지. 현재 모든 환경 변수가 날아가서 완성된 프론트엔드 초기본을 보지 못하는게 아쉽다.
왜 그렇게 오래 걸렸을까?
- "AI 에이전트를 쓰면 내 실력이 늘지 않을 거야"라는 기술적 똥고집.
- 사실은 그저 코드를 타이핑하는 행위 자체가 주는 즐거움(도파민)에 취해 있었다.
- "함수형 패러다임을 마스터하겠다"며 불필요한 리팩토링을 반복했다.
- 기획 부재의 나비효과: "어차피 1인 개발인데 문서가 뭐가 중요해?"라며 기획서 없이 머릿속으로만 구상했다.
- 백엔드 통합의 좌절: 프론트엔드를 대충 완성하고 백엔드를 붙이려니, 스파게티처럼 꼬인 코드들이 발목을 잡았다. 뒤늦게 문서를 쓰려 했지만, 이미 내 머릿속 기획은 산화되었고 코드는 걷잡을 수 없었다. 결국 프로젝트 종료.
1.2 무엇이 망함의 원인이었나?
1) '무엇(What)'을 만들지 정하지 않았다.
나는 문제 해결보다 '코드 타이핑'을 즐겼다. '무엇을' 만들지보다 '어떻게' 만들지에만 집착했다. 문서와 기록 없이 그날그날 만들고 싶은 기능을 만들고 이슈를 생성하길 반복했다.
무엇을 만들지 정해두지도 않으니 그냥 그 날 그 날 만들고 싶은걸 만들었다.
결국 시간이 흘러 무언가를 만들긴 했는데, **"도대체 내가 뭘 만든 거지?"**라고 자문하게 되는 아이러니한 상황이 발생했다.
2) 쓸데없는 고집, 코드 타이핑 중독
당시엔 실력 향상을 위해 AI를 쓰는 것을 죄악이라 생각했다. 하지만 지금 와서 보면, 내가 3개월간 짠 프론트엔드 로직은 AI 에이전트를 쓰면 이틀이면 만들 수 있는 볼륨이었다.
2. 두 번째 실패: 도구는 챙겼지만 프로세스가 부족했다 (25.09 - 25.11)
2.1 지난 실패에서 배운 점
1) AI 에이전트를 쓰지 않는 건 바보 같은 짓이다.
내가 사장이고 나 같은 개발자를 고용했다고 상상해 봤다. 하드 코딩을 고집하며 3개월을 날리고 실패한 프로덕트를 가져온다면? 정말 복장이 터질 일이다.
note내가 만드는 것은 '서비스'이지, '글자들로 이뤄진 코드 덩어리'가 아님을 인정해야 했다.
내 성장은 물론 중요하지만, AI를 활용해서 더 많은 것을 얻을 수 있음을 받아들이기로 했다.
2) 내 뇌는 너무 작다 (기록의 중요성)
딩딩 달려라 나의 작은 뇌
내 뇌는 용량이 한정적이고 비효율적이다. 밤에 작업하고 아침에 일어나면 아이디어가 기억나지 않는 '컨텍스트 스위칭' 비용을 줄이기 위해, 철저한 문서화를 결심했다.
2.2 개선한 점 (Action Plan)
1) 프로젝트 시작 전 문서화 (feat. AI)
image
프로젝트 시작과 동시에 필요한 문서를 정리했다. 어떤 문서가 필요한지조차 모를 때는 AI에게 리스트를 요청하고, 역으로 질문을 받아 답해가며 내용을 채웠다.
2) AI 에이전트 협업을 위한 Iteration 개발 기법 도입
현재는 사용하지 않는 문서이지만 이 프로젝트때는 작업 시작 전 매번 TODO 파일을 만들었다.
생성되는 TODO 파일의 예시
브랜치를 생성할 때마다 다음과 같은 프로세스를 강제했다.
- TODO 작성: 해당 브랜치에서 할 일을 Iteration 단위로 나누어 문서화한다.
- 검토: 생성된 Iteration 계획을 검토한다.
- 위임: AI 에이전트에게 해당 Iteration에 맞춰 작업을 지시한다.
이렇게 하니 내가 통제 가능한 수준의 'Vibe Coding'이 가능했고, 자연어 문서를 통해 작업 내역을 명확히 추적할 수 있었다.
3) 꾸준한 기록과 관리 (Notion 활용)
코드 에디터 밖에서의 관리도 중요함을 깨닫고 노션을 적극 활용했다.
- 전체 프로젝트를 테스트 가능한 단위로 분할
- 각 단위를 영역(FE, BE, Design)별로 분할
- 순차적 진행
3. 그럼에도 여전히 실패 포인트는 존재했다
3.1 수평적(Horizontal) 개발의 함정: 컨텍스트 스위칭 비용
첫 번째 실패보다는 나아졌지만, 여전히 치명적인 문제가 있었다. 나는 본능적으로 수직적(기능 단위) 개발이 아닌 수평적(레이어 단위) 개발을 하고 있었다.
기능 A를 만들 때, 프론트엔드 작업을 100% 완료한 뒤 백엔드 작업으로 넘어가는 식이었다.
- 문제 상황: 기능 A의 볼륨이 커서 프론트엔드 작업 후 며칠 뒤 백엔드를 작업하게 됨.
- 비용 발생: 백엔드를 개발하다 보니 프론트엔드 데이터 구조 변경이 필요함. -> 다시 프론트엔드 코드로 돌아가야 함. -> "이 코드 왜 이렇게 짰더라?" (컨텍스트 휘발) -> 이슈 다시 파고 병합하는 과정의 반복.
결국 혼자서 모든 레이어를 다루는 1인 개발자에게, 이런 수평적 접근은 막대한 컨텍스트 스위칭 비용을 야기한다는 것을 뼈저리게 느꼈다.
3.2 바퀴를 다시 발명하지 마라: 직접 구현의 늪 (Reinventing the Wheel)
서비스의 주축이 되는 에디터 기능을 라이브러리 없이 직접 구현하려다 3주라는 금 같은 시간을 또다시 허비했다.
나는 왜 그랬을까? "라이브러리 공식 문서를 읽고 학습하는 것보다, AI 에이전트에게 시켜서 뚝딱 만드는 게 더 빠르고 간단하겠지?"라는 안일한 생각 때문이었다.
하지만 '기능을 구현한다' 는 것은 단순히 겉모습(View)을 만드는 게 아니었다. 보이지 않는 거대한 프로세스가 뒤따른다.
- 기능 구현에 필요한 기획 및 문서 생성
- 발생 가능한 모든 엣지 케이스(Edge case)에 대한 버그 예측 및 해결
- 기능 구현 (코딩)
- 퀄리티 체크 (QA)
- 기능이 추가되면 1번부터 무한 반복
나는 수천 명의 기여자가 다듬어 놓은 오픈소스 라이브러리의 퀄리티를 내가 혼자서(그것도 AI의 도움만으로) 단숨에 따라잡을 수 있을 것이라 오판했다. 그 결과는 처참한 퀄리티와 시간 낭비였다.
결말은 허무했다.
3주 동안 끙끙대며 만들다 포기한 그 기능을, 라이브러리 문서를 30분 정도 정독하고 에이전트에게 맡기니 단 5분 만에 내가 원하던 것보다 훨씬 완벽하게 구현되었다.
4. 해결책: 실패를 딛고 프로세스를 혁신하다
4.1 수평적(Horizontal)에서 수직적(Vertical)으로: 케이크를 자르는 법
이전의 실패들을 교훈 삼아, 이제는 작업 단위를 수평적 레이어가 아닌 '수직적 슬라이스(Vertical Slicing)' 단위로 나누어 진행하고 있다.
쉽게 말해 '기능 단위'로 개발하는 것이다. 이 차이를 가장 잘 설명해 주는 것이 바로 '케이크 만들기' 비유다.
- 수평적 접근 (기존의 나): 케이크 시트(DB)를 전부 굽고, 그 위에 생크림(Server)을 전체적으로 바르고, 마지막에 토핑(Client)을 얹는다.
- 문제점: 토핑을 얹을 때가 되어서야 시트가 맛이 없다는 걸 알게 된다. 이미 늦었다.
- 수직적 접근 (지금의 나): 조각 케이크(Feature) 하나를 완성하기 위해 시트, 생크림, 토핑을 한 번에 만든다.
- 장점: 조각 케이크 하나를 먼저 먹어보고(테스트), 맛이 없으면 즉시 레시피를 수정할 수 있다.
내 프로덕트의 핵심인 **'AI 기반 첨삭 영어 일기 에디터'**를 예로 들면 개발 순서는 다음과 같이 바뀐다.
[Step 1] 핵심 가치(Core Value) 구현: "못생겨도 일단 돌아가게 만든다"
- (FE) 디자인 없는 뼈대 UI 생성 (input, button)
- (BE) 기본적인 CRUD를 지원하는 라우트 핸들러 구현
- (DB) 데이터 저장을 위한 스키마 설계 및 연동
note결과물: 디자인은 엉망이지만, 일기를 쓰고 저장하면 DB에 꽂히는 '동작하는' 기능
[Step 2] 고도화 및 안정화: "예쁘고 튼튼하게 다듬는다"
- (FE)
shadcn/ui등을 활용한 UI 디자인 고도화 및 UX 개선 - (BE) 예외 처리(Error Handling) 및 다양한 엣지 케이스 대응
- (DB) 정규화 점검 및 데이터 무결성 보장
note결과물: 사용자가 실제로 쓸 수 있는 완성된 기능
4.1.1 그래서 수직적 작업 구조(Vertical Slicing)가 1인 개발자에게 왜 좋은가?
이 방식을 도입하고 나서 느낀 장점은 명확했다.
1. 컨텍스트 스위칭 비용의 제로(0)화
가장 큰 문제였던 '기억의 휘발'이 사라졌다. 프론트엔드 코드를 짜면서 동시에 백엔드 코드를 만지기 때문에, 내 머릿속은 온전히 '일기 저장'이라는 하나의 기능에만 집중하면 된다. "아, 아까 백엔드 데이터 구조를 어떻게 짰더라?"라고 고민할 필요가 없다. 지금 바로 내 눈앞에 있으니까.
2. 즉각적인 피드백과 빠른 수정 (Fail Fast)
수평적으로 개발할 때는 백엔드를 다 만들고 프론트엔드를 붙일 때쯤 설계 미스를 발견하곤 했다. 하지만 수직적으로 개발하니, 아주 작은 단위(Step 1)에서 데이터 흐름의 문제를 바로 발견하고 수정할 수 있다. 호미로 막을 것을 가래로 막는 일이 사라졌다.
3. '동작하는 소프트웨어'가 주는 도파민
이건 심리적인 부분인데 1인 개발자에게 매우 중요하다. 수평적 개발을 할 때는 며칠 동안 백엔드 코드만 짜다 보니 화면에 보이는 게 없어 지루했다. 하지만 수직적 개발은 작업 시작 1~2시간 만에 비록 못생겼을지언정 '실제로 동작하는 기능' 을 눈으로 볼 수 있다. 이 작은 성취감들이 모여 프로젝트를 완주할 수 있는 원동력이 된다.
4.2 잦은 회고를 통한 지속적 성장 도모
프로젝트를 2번이나 실패하고 갈아엎었던 것의 원인은 물론 잘못된 방식으로 진행했던 문제도 있지만 문제점을 늦게 발견하 것도 큰 몫을 한다.
실패를 늦게 발견 할 수록 수습하기 위한 비용은 커지고 나는 매번 가장 늦게 발견해서 수습이 불가하다 판단하여 갈아엎었다.
만약 내가 작업 단위를 더 작게 하고 각 작업 단위마다 회고를 가졌다면이란 후회가 든다.
지속적 성장을 위한 회고의 필요성을 이번에 깨닫고 이와 관련된 책을 대여하여 읽고 있다. (함께 자라기라는 책이다.) 회고를 통한 성장은 프로덕트나 개발자로서의 커리어 뿐 아니라 내 삶에도 적용 할 수 있는 일이기 때문에 이와 관련해서 생각을 계속 해봐야겠다 깨달았다.