뒤로가기
개발자가 MVP를 만들 때 하는 실수들

August 18, 2022

side-projectcareer

작년에 사이드 프로젝트로 MVP를 만들겠다고 했다. 프리랜서 개발자들이 프로젝트를 관리할 수 있는 간단한 대시보드. 기능은 단순했다. 진행 중인 프로젝트 목록, 마감일, 입금 여부 체크. Notion으로 해도 되는 수준이었다.

3주 뒤 내 프로젝트 구조를 보자.

모노레포. Turborepo로 세팅해서 packages 폴더 안에 ui 라이브러리, shared utils, 타입 정의 패키지를 분리했다. 디자인 시스템 패키지에는 Button, Input, Modal, Toast 컴포넌트가 Storybook과 함께 들어있었다. 백엔드는 별도 서비스로 분리할 계획이라 API 게이트웨이 패턴을 준비 중이었다. 테스트 커버리지 목표는 80%.

사용자 수: 0명.

이게 개발자가 MVP를 만들 때 가장 자주 하는 실수의 전형이다. MVP의 M이 Minimum이라는 걸 잊어버린다.

과잉 설계의 유혹#

왜 이렇게 되는 걸까. 단순하다. 우리에게는 "좋은 코드"에 대한 기준이 있으니까. 회사에서 코드 리뷰를 하고, 기술 블로그를 읽고, 컨퍼런스 발표를 들으면서 내재화한 기준. 관심사 분리, 재사용 가능한 컴포넌트, 확장 가능한 아키텍처, 적절한 테스트 커버리지.

이 기준 자체는 나쁘지 않다. 팀에서 장기간 유지보수할 프로덕션 코드에는 필요하다. 문제는 이 기준을 MVP에도 적용한다는 거다. MVP는 "이 제품이 의미가 있는가?"를 확인하는 실험이다. 실험에 프로덕션 수준의 코드 품질은 필요 없다.

Paul Graham이 쓴 "Do Things That Don't Scale"에서 인상적인 부분이 있다. Airbnb 초기에 창업자들이 뉴욕의 호스트를 한 명씩 직접 방문해서 사진을 찍어줬다고 한다. 확장 가능한 방식이 전혀 아니다. 근데 그게 효과가 있었고, 사용자가 늘어나면서 나중에 자동화했다. 처음부터 "사진 자동 보정 AI 시스템"을 만들었으면 어땠을까. 제품이 출시도 되기 전에 기술에 매몰되어 있었을 거다.

Stripe도 비슷하다. Stripe의 창업자인 Collison 형제가 초기에 한 일은, 잠재 고객한테 직접 찾아가서 결제 시스템을 대신 연동해주는 거였다. API 문서를 보내고 "알아서 연동하세요"가 아니라, 노트북을 들고 가서 그 자리에서 세팅했다. 이걸 "Collison installation"이라고 부른다. 확장 불가능하지만, 초기 사용자의 진짜 니즈를 몸으로 배우는 과정이었다.

진짜 MVP는 어떤 모습인가#

내가 아는 한 시니어 개발자가 퇴사하고 만든 서비스가 있다. 소규모 쇼핑몰 사장님들이 인스타그램 DM으로 주문을 받을 때 쓰는 자동화 도구. 첫 버전의 구현이 어땠냐면.

프론트엔드: 없었다. 말 그대로 없었다.

사장님이 주문 양식을 구글 폼으로 만들어서 인스타 프로필에 링크를 건다. 주문이 들어오면 구글 시트에 자동으로 쌓인다. 그 시니어가 만든 건, 구글 시트의 데이터를 읽어서 택배사 API에 송장 등록을 해주는 Apps Script 하나였다.

이게 MVP였다. 기술적으로는 초라하다. 근데 이 MVP로 확인한 게 있다. "쇼핑몰 사장님들이 DM 주문 처리에 시간을 엄청 쓰고 있고, 이걸 자동화하면 돈을 낼 용의가 있다"는 사실. 첫 달에 유료 사용자 8명이 붙었다. 월 3만 원씩.

여기서 중요한 건, 사장님들은 그 뒤에 Apps Script가 돌아가는지, 서버리스 함수가 돌아가는지, 마이크로서비스가 돌아가는지 전혀 신경 안 쓴다는 거다. 자기 일이 줄어드는지만 본다.

이 시니어가 프론트엔드를 만들고, 대시보드를 만들고, 제대로 된 서비스로 확장한 건 유료 사용자가 30명을 넘긴 후였다.

MVP에 필요 없는 것들 목록#

구체적으로 적어본다. MVP 단계에서 내가 시간을 썼지만 필요 없었던 것들.

디자인 시스템. 버튼 컴포넌트의 variant를 primary, secondary, ghost, outline으로 나누고 사이즈를 sm, md, lg, xl로 만들 필요가 없다. 그냥 하나면 된다. 색깔도 하나면 된다. Tailwind UI나 shadcn/ui에서 필요한 것만 복붙해서 쓰면 된다. 디자인 일관성은 사용자가 100명 넘으면 그때 고민해도 늦지 않다.

마이크로서비스. 사용자가 0명인 서비스에 마이크로서비스 아키텍처는 모순이다. 모놀리스로 충분하다. 사실 모놀리스도 과하다. 서버리스 함수 몇 개로 될 수도 있다. 아니면 위에서 본 것처럼 Google Apps Script로 될 수도 있다.

100% 테스트 커버리지. 핵심 비즈니스 로직에 대한 최소한의 테스트면 된다. 결제 금액 계산이 맞는지, 데이터가 유실되지 않는지 정도. 나머지는 직접 클릭해보면서 확인하면 된다. 사용자가 적을 때는 버그가 나도 빠르게 고치면 된다.

인증 시스템 직접 구현. OAuth 플로우를 직접 만들 필요가 없다. NextAuth든 Clerk든 Auth0든, 기존 서비스를 쓰면 된다. 아니, 초기에는 이메일과 비밀번호로 가입하는 것 자체가 사용자한테 허들이다. 비밀번호 없이 이메일 매직 링크로 가는 게 낫다. 아니면 더 과감하게, MVP 단계에서 인증 자체가 필요한지를 다시 생각해봐야 한다.

CI/CD 파이프라인. Vercel에 연결하면 git push만 하면 배포된다. GitHub Actions로 정교한 파이프라인을 구성하는 건 팀이 생긴 후에 해도 된다.

반응형 디자인. 타겟 사용자가 모바일 위주인지 데스크톱 위주인지 파악하고, 한쪽만 먼저 만든다. 둘 다 지원하려면 시간이 배로 든다.

First Round Review에서 본 문장이 있다. "No company swag until the business has at least $250K of revenue or 250k users." 매출 25만 달러나 사용자 25만 명이 될 때까지 회사 굿즈를 만들지 말라는 거다. 사업의 느낌이 나는 것들에 시간을 쓰지 말고 본질에 집중하라는 뜻인데, 개발자한테는 이렇게 번역할 수 있다. "유료 사용자가 50명이 될 때까지 아키텍처 리팩토링을 하지 마라."

"나중에 갈아엎어야 하면 어떡해" 증후군#

이 반론이 항상 나온다. "지금 대충 만들면 나중에 기술 부채 때문에 힘들어지지 않냐?" 맞다. 힘들어진다. 근데 그 "나중"이 올 확률이 얼마나 될까.

대부분의 사이드 프로젝트는 유료 사용자를 한 명도 만들지 못하고 죽는다. 정성 들여 짠 클린 코드가 아무도 안 쓰는 레포에서 먼지를 쌓고 있다. 그 코드를 갈아엎을 일이 없다. 애초에 쓰는 사람이 없으니까.

기술 부채가 문제가 되는 건, 서비스가 성장해서 사용자가 늘고 팀원이 들어왔을 때다. 이건 좋은 문제다. 사용자가 늘어서 코드를 리팩토링해야 하는 상황은, 아무도 안 쓰는 깨끗한 코드보다 100배 낫다.

Sam Altman이 "Plans should be measured in decades, execution should be measured in weeks"라고 했다. 장기적 비전은 크게 갖되, 실행은 주 단위로 하라는 거다. MVP는 이 "주 단위 실행"의 결과물이어야 한다. 몇 달이 걸리면 이미 MVP가 아니다.

개발 시간 vs 검증 시간#

내가 사이드 프로젝트에 투자한 시간을 돌아보면 이렇다.

기술 스택 선정: 3일. 프로젝트 세팅: 2일. 디자인 시스템 구축: 1주. 핵심 기능 개발: 2주. 부가 기능 개발: 2주. 배포 환경 구성: 2일. 랜딩 페이지: 3일.

총 약 6주.

이 6주 동안 잠재 사용자와 대화한 시간: 0시간.

이게 문제다. 6주를 들여서 만든 게 사람들이 원하는 건지 아닌지를, 만들고 나서야 확인하려 한다. 만약 2주 차에 사용자 인터뷰를 했으면? 기능의 절반은 필요 없다는 걸 알았을 수도 있다. 아예 방향을 틀었어야 한다는 걸 알았을 수도 있다.

이상적인 비율은 뒤집어져야 한다. 만드는 시간보다 확인하는 시간이 더 많아야 한다. 1주일에 3일은 만들고, 4일은 사람들한테 보여주고 피드백을 받는다. 물론 현실적으로 재직 중에 이 비율을 맞추긴 어렵다. 근데 최소한 "만드는 시간 100%, 확인하는 시간 0%"에서는 벗어나야 한다.

First Round Review에서 읽은 또 다른 조언이 있다. "You'll know you understand the customer problem enough when you can predict 75% of what a customer tells you." 고객이 말할 내용의 75%를 예측할 수 있으면 문제를 충분히 이해한 거라는 뜻이다. 이 수준에 도달하려면 코드를 짜는 게 아니라 사람을 만나야 한다.

실용적인 MVP 접근법#

지금 만들고 있는 사이드 프로젝트가 있다면, 이렇게 해보면 어떨까.

기능 목록을 적는다. 다 적는다. 그리고 절반을 지운다. 남은 것에서 또 절반을 지운다. 그래도 제품이 성립하면, 처음 지운 75%는 MVP에 필요 없었던 거다.

기술 스택은 가장 익숙한 걸로 한다. 새로운 기술을 배우면서 MVP를 만드는 건, 두 개의 불확실성을 동시에 안고 가는 거다. "이 기술이 내 프로젝트에 맞을까?"와 "이 제품이 시장에 맞을까?"를 동시에 검증하면 어느 쪽이 실패한 건지 구분할 수 없다.

데드라인을 건다. 2주. 길어도 4주. 그 안에 사람한테 보여줄 수 있는 뭔가가 나와야 한다. 데드라인이 있으면 자연스럽게 스코프가 줄어든다. "이것도 넣고 싶은데 시간이 없으니까 다음에" 가 된다. 이 "다음에"가 대부분 영원히 안 와도 괜찮다.

그리고 가장 중요한 건, "부끄러운 수준"에서 공개하는 거다. LinkedIn의 공동창업자 Reid Hoffman이 "If you are not embarrassed by the first version of your product, you've launched too late"라고 했다. 첫 버전이 부끄럽지 않으면 너무 늦게 출시한 거라는 뜻이다.

내가 완벽주의를 버리게 된 계기가 있다. 어떤 서비스의 초기 버전 스크린샷을 봤는데, CSS가 깨져 있고, 폰트가 기본 폰트이고, 여백이 들쭉날쭉했다. 근데 사용자가 있었다. 돈을 내는 사용자가. 결국 중요한 건 디자인이 예쁜지가 아니라, 문제를 해결하는지다.

MVP는 질문이다. "이걸 원하는 사람이 있나?" 그 질문에 대한 답을 가장 빠르게 얻는 방법이 좋은 MVP다. 코드의 양이 아니라 학습의 양으로 측정해야 한다.