AI시대: 바이브 코딩으로 웹앱 만들기

AI를 이용한 코딩을 이야기 하다 보면, 마치 자연어 몇마디로 앱이나 서비스가 뚝딱 완성되는 것처럼 느껴질 때가 있습니다. 실제로 바이브코딩 (Vibe Coding) 이라는 표현 자체도 그런 분위기 속에서 더 확산되고 있습니다.

저는 이전 글에서 AI 코딩이 How의 민주화라는 큰 흐름 위에 있고, 구현이 쉬워질수록 What의 중요성이 올라간다는 이야기를 한 적이 있습니다.

이번 글에서는 바이브코딩을 이용해서 제가 직접 저희 가족이 사용할 웹앱을 만들어본 경험을 정리해 보았습니다.

결론부터 말하면, 상상했던 것처럼 말 몇마디에 모든걸 완성하는 건 (당연히) 불가능 했습니다. 다만, 90% 정도의 완성도를 가진 결과물을 10~20배 빠른 속도로 완성할 수 있었던 것은 분명한 사실입니다. 저는 아주 손이 빠른 스마트한 주니어 엔지니어 몇명 데리고 작업을 진행하는 느낌을 받았습니다. 방향과 판단은 제가 하고, 그 외 모든 구현과 정리 작업은 AI가 가져가는 협업 구조였습니다.


목 차


구현 대상: My Lesson Log 1.0

먼저 어떤 앱을 만들고자 했는지 간단하게 정리하겠습니다.

My Lesson Log는 공부할 때 나타나는 반복적인 습관을 기록하고, 통계 기반으로 패턴을 도출하고, 어떻게 교정해 나갈지 루틴을 만들어가는 개인용 학습 기록 도구입니다. 원래는 엑셀 기반으로 간단하게 기록하려고 하다가 사용성을 고려하여 웹앱 형태로 만들게 되었습니다.

처음엔 간단한 UI를 Notion DB에 연결하는 정도를 염두에 두고 AI와 장시간 상의하며 다각도로 요구사항을 정제했습니다. 결국 개발 편의성, 사용성, 유지보수성 등에 대한 Tradeoff를 모두 고려한 끝에 전형적인 프론트엔드 + 백엔드 구조를 갖는 웹앱으로 가기로 했습니다.

최종 앱은 기록, 목록, 통계, 루틴, 노트, 설정 등 총 여섯 개 화면으로 구성되며, 다음과 같은 기능을 가집니다.

  • 습관 기록: 문제 상황과 습관을 빠르고 쉽게 입력
  • 데이터 기반 분석: 기간, 과목, 습관 유형별 통계 제공
  • 패턴 인사이트: 반복되는 습관 패턴을 시각적으로 발견
  • 루틴 제안: 분석 결과를 바탕으로 맞춤 루틴 자동 생성
  • 데이터 내보내기: CSV 다운로드로 나만의 데이터 관리

Google 계정 로그인으로 사용자별 데이터가 분리되고, PC와 모바일 양쪽에서 같은 데이터를 볼 수 있습니다.

시스템 구조

사용자 디바이스(PC/모바일 브라우저)에서 React + TypeScript + Vite 기반의 SPA(Single Page Application)가 동작하고, 백엔드는 Firebase로 묶었습니다. Firestore에 데이터를 저장하고, Authentication으로 사용자 인증을 하고, Hosting으로 자원을 서빙하는 방식입니다. 보유 중인 커스텀 도메인을 Firebase Hosting에 연결해 운영 주소로 사용했습니다.

처음부터 이러한 구조를 정하고 시작한 건 아닙니다. AI와 구현 방향을 의논하면서 Notion DB → 커스텀 백엔드 → Firebase 순으로 좁혀온 결과입니다. 풀스택 전체를 직접 구축하는 것은 운영 부담이 너무 컸고, Notion API는 사용자별 인증과 보안 규칙을 깔끔하게 풀기 어려웠습니다.

Firebase는 인증, DB, 호스팅이 한 묶음으로 제공되어 1인 운영에 적합한 선택이라고 판단하였습니다. 이 결정이 이후 작업 속도에 가장 큰 영향을 주었습니다. Firebase 생태계가 충분히 표준화되어 있기 때문에, AI가 작업을 진행하는 데에 별 어려움이 없었고, 충분한 속도를 낼 수 있었습니다.

다만 인증, DB, 호스팅이 모두 Firebase로 묶여 있다는 점은 양날의 검이기도 했습니다. 한 영역의 실수가 다른 영역의 동작 문제로 번지는 일도 있었습니다.

커스텀 도메인 연결까지 포함해 작업 시작부터 최종 배포까지 총 3일이 걸렸습니다.


구현 과정: 이상 vs 현실

구현을 시작하면서, 자연어 몇 마디로 모든 것이 해결되는 마법은 기대하지 않았습니다. 다만 뉴스 기사나 SNS에 많이 보이는 글처럼, 상위 레벨의 요구사항을 자연어로 잘 정리해서 전달하면, 이후 세부 구현 과정은 비교적 매끄럽게 흘러갈 것이라는 기대는 있었습니다.

Notion 기반으로 만들어둔 입력 양식을 출발점으로 해서 기록 조회 및 통계 화면까지 갖춘 쓸만한 앱으로 발전시키고, 백엔드 배포까지 자연스럽게 마무리되는 것을 예상했습니다. AI가 코드를 만들면 저는 그 결과물을 검토하고 다음 방향을 정해주면 되는 정도로 생각했습니다.

하지만, 실제 과정은 제 예상과는 좀 달랐습니다.

① AI의 방향에 대한 적극적인 개입 필요

AI가 내놓는 결과물은 대부분 합리적으로 보였습니다. 다만 그 합리적인 안이 실제 이 앱에서 기대하는 흐름에 어긋나는 경우가 자주 있었고, 그때마다 “잠깐, 그쪽이 아니다”라고 방향을 잡아줘야 했습니다. AI가 제안을 하면, 그 제안을 그대로 받아들이지 않고, 한 번 더 따져보는 일이 작업 내내 반복됐습니다.

대표적으로 환경의 문제를 코딩으로 해결하려는 경우가 있었습니다. Google 로그인이 안 되는 문제가 대표적입니다. AI는 인증 창을 띄우는 방식을 pop-up 에서 redirect로 바꿔보고, 다시 pop-up으로 돌리는 식으로 계속 코드를 수정했습니다. 그런데 실제 원인은 코드가 아니라 OAuth Client에 등록된 도메인 주소 때문이었습니다. OAuth Client에는 “localhost”만 등록되어 있었는데, 로컬 dev server는 “127.0.0.1"로 실행이 되다보니, 인증에 실패를 했던 것입니다. 코드 바깥의 설정 화면을 함께 봐야 풀리는 문제였죠.

또, 일반적인 방법을 적용했으나, 이 앱의 개발 환경과 맞지 않는 경우도 있었습니다. AI는 서버 데이터 저장에 실패할 때를 대비해 브라우저 저장소를 fallback으로 이용했습니다. 일반적으로는 합리적으로 보였습니다. 그런데 PC-모바일 등 다양한 클라이언트에서 같은 데이터를 봐야 하는 구조에서는, 그 fallback으로 인해 PC-모바일 간 데이터 동기화가 안되는 것처럼 보이는 문제를 만들었습니다. Firestore 단일 저장소를 이용하고, 저장 실패 시 메시지를 출력하는 것으로 정리하였습니다.

중간 결정을 임의로 진행하는 경우도 잦았습니다. 설정 화면에서 선택지를 삭제하는 기능을 만들 때, AI는 자연스럽게 Firestore 문서를 실제로 삭제했습니다. 하지만 기존 기록들이 그 선택지를 참조하고 있었기 때문에, 실제 삭제가 아니라 플래그로 처리해야 기존 데이터 표시가 깨지지 않습니다. 또 선택지를 수정할 때도 그 선택지를 참조하고 있는 기존 기록들은 수정하지 않고, 설정 내 선택지만 수정을 하는 바람에 수정 전 데이터가 표시되는 상황이 발생했습니다. 결국 정확한 요구사항을 말해주지 않으면 AI는 가장 편리한 길로 가버렸습니다.

작업 내내 “이건 그럴듯한 합리적인 안”인가, 아니면 “이 앱에 맞는 안인가”를 계속 구분해야 했습니다.

사용자의 도메인 지식 격차가 작업 속도를 결정

개발을 진행하다 보니, 저의 도메인 지식 수준에 따라 작업 영역 별로 체감 속도가 달랐습니다. 제가 잘 아는 영역에서는 적극적으로 개입해서 시간을 크게 줄일 수 있었습니다. 화면 구조, 사용성, 데이터 모델 같은 부분은 빠르게 판단할 수 있어서 AI의 산출물을 즉시 받아들이거나 즉시 끊어낼 수 있었습니다.

반면 제가 잘 모르는 영역에서는 시간이 더 걸렸습니다. Firestore Security Rules, OAuth Client 설정과 Firebase Auth handler의 관계, 인앱 브라우저 User-Agent 감지 같은 영역은 AI가 코드를 만들어주는 것과 별개로, 제가 그 내용을 이해해야 검증이 가능했습니다. 경우에 따라서는 AI와 대화를 따라가기 위해 웹 검색을 병행하면서 개념을 익혀야 했습니다.

다만 AI가 없던 시절과 비교해 보면, 그때는 모르는 부분에 대한 공부도 더 깊이, 더 정확하게 했어야 하지만, 지금은 대략적인 개념 이해만으로도 작업 속도를 높이기에 충분했습니다.

③ 요구사항 구체화의 어려움, 특히 UI

“통계가 필요하다”, “모바일에서도 동작해야 한다” 같은 상위 레벨의 요구사항은 자연어로 전달이 잘 됐습니다. 문제는 그 아래 수준이었습니다. 요구사항을 구체화 할수록 자연어로만 전달하는데에는 한계가 드러났습니다. 수치화된 기준으로 명확하게 전달해야 하는데, 자연어로 이야기를 하다 보면, 마치 사람과 이야기하는 듯한 느낌으로 피드백을 전달했던 것 같습니다.

UI 쪽이 특히 어려웠는데요. 예를 들면, “표 컬럼이 너무 좁다”, “이 정도면 적당하다”와 같은 모호한 표현을 쓰게 되는 거죠. 결국 스크린샷을 보며 “날짜 컬럼은 다 보여야 한다”, “좌우 여백은 50% 더 줄여도 된다”, “세로 줄이 있는 표로 만들어 줘”라는 식으로 점점 더 명확한 피드백을 반복했습니다.

PC와 모바일을 어떻게 다르게 보여줄지도 마찬가지였습니다. “모바일은 따로 디자인되어야 한다”는 방향은 잡혔지만, 표 기반의 PC 화면과 카드 형태의 모바일 화면을 최종 결정하기까지는 수차례 수정을 반복했고, 화면을 직접 보면서 다듬는 과정을 거쳤습니다.

과제 성격이나 구성원에 따라서 다르겠지만, 일반적으로 바이브 코딩을 통해 빠르게 앱을 만드는 경우에는 초기 단계에 결정할 수 없는 부분들에 대해서, AI와 어떤 절차와 방식으로 정리를 해나갈지 미리 고민해 둘 필요가 있을 것 같습니다.

결국 의사결정의 연속이었다

3일 동안 제가 직접 작성한 코드는 거의 없었고, 의사결정만 계속했습니다. 화면 구조를 합칠지 분리할지, 어떤 용어를 사용할지, 안전장치를 어떻게 구성할지, AI가 우회하려 할 때 본질로 돌리기 같은 결정들입니다.

사실 전통적인 접근 방법에 따르면, 개발 중간에 방향을 바꾸는 것은 큰 비용이 듭니다. 그래서 가능한 많은 결정사항들을 미리 정하고 개발을 시작하는 것이 좋습니다. 하지만 AI 코딩의 시대에는 중간에 구현이나 구조를 바꾸는 비용이 상대적으로 덜 듭니다. 빠른 구현을 위해서 꼭 필요한 사항들만 먼저 결정을 한 후 개발을 시작하고, 후속 결정들은 결과물을 보면서 정해도 늦지 않는 것 같습니다.

도입부에서 말씀드린 “손이 빠른 스마트한 주니어 엔지니어 몇 명을 데리고 일하는 느낌”의 실체가 이것이었습니다. AI는 코드를 빠르게 처리하고, 저는 그 결과를 보고 다음 방향을 정하는 일을 계속했습니다. 자연어로 모든 게 자동으로 풀리는 게 아니라, 자연어로 끊임없이 방향을 잡아주는 일이었습니다.


사람과 AI의 역할 분담

이런 과정을 거치면서, 사람과 AI의 역할이 꽤 명확하게 나뉘었다는 점을 다시 한번 알게 됐습니다. 일을 단순히 둘로 나눈 게 아니라, 작업의 성격에 따라 What / How / Verify 각 영역별로 자연스럽게 정리됐습니다.

What(의도, 방향), 사람의 역할이 중요

What은 AI가 도와줄 수 있는 영역이 가장 적었습니다. “이 앱이 왜 필요한가”, “어떤 사용자 흐름이 핵심인가”, “지금 이 결정이 옳은 방향인가” 같은 질문은 결국 사람의 판단입니다.

예를 들어, 이 앱에서 기록하고자 하는 내용이 무엇이고, 사용자에게 어떤 인사이트를 제공하고 싶은지에 대한 판단, 사용자의 실 사용환경을 고려한 PC와 모바일 화면 구성 및 테마 적용 등은 AI가 합리적 제안을 빠르게 만들 수는 있어도, 어느 쪽이 맞는지는 사용 맥락을 아는 사람만 정할 수 있었습니다.

How(설계, 구현), AI가 압도적으로 빠르되, 사람의 적극적 피드백 필요

How는 AI가 가장 큰 역할을 하는 영역입니다. CSS, Firebase 보안 규칙, 마이그레이션 스크립트, 인앱 브라우저 감지 같은 코드를 즉시 만들어 줬습니다. 제가 잘 모르는 영역도 검증만 하면 됐습니다.

다만 이 부분에서도 사람의 역할이 결정적으로 필요한 순간이 있었습니다. 가령 AI가 임시방편으로 우회하려 할 때, 예외상황 처리 때문에 앱의 본질을 가리려 할 때, 합리적으로 보이는 제안이 실제 사용 맥락과 안 맞을 때 등 이에 대한 적극적인 피드백을 주고 방향을 바로 잡게 하는 일은 AI 스스로는 못 합니다. How는 AI가 90%를 가져가지만, 사람의 10% 피드백이 없으면 나머지 90%도 잘못된 방향으로 갑니다.

Verify(검증, 정리), 역할 분담이 가장 잘 맞은 영역

Verify는 사람과 AI의 역할 분담이 자연스러웠습니다. AI는 테스트 케이스를 빠짐없이 나열하고, 각종 문서를 일관된 형식으로 정리하고, PR을 만들고 conflict를 해결합니다. 사람은 그 결과물이 실제 사용 맥락에 맞는지, 빠진 시나리오가 없는지를 확인합니다.

문서의 역할

AI를 이용하면 문서작성에 드는 노력을 압도적으로 효율화할 수 있습니다. 사람이 직접 했다면 귀찮아서 빠뜨렸을 항목들을 AI는 빠짐없이 채웠습니다. 이번에 앱을 개발할 때는 README, TEST_CASES, RELEASE_NOTES, RETROSPECT 같은 문서들이 꽤 자세하게 남아 있습니다. 예전 같으면 대충 넘어갔을 가능성이 높습니다.

그런데 더 흥미로운 건, AI와 작업할 때는 문서가 사람만을 위한 자료가 아니라는 점입니다. 오히려 AI에게 프로젝트의 맥락을 계속 주입하는 메모리 역할을 합니다. 중간에 작업 PC를 바꾸고 새로운 세션을 시작했는데, 이때 “이 repo를 새로 clone 했어. HANDOFF.md 읽고 이어서 작업해줘”라는 한마디로 맥락이 복원되었습니다. HANDOFF 외 기존에 작성한 문서들을 모두 읽은 뒤 작업을 다시 시작하는 흐름이 만들어졌습니다.

즉, 문서가 사람을 위한 설명서이면서 동시에 AI 협업 인터페이스로 바뀌고 있었습니다. 문서를 잘 쓴다는 건 이제 사람이 읽기 좋은 글을 쓰는 일이면서 동시에 AI가 빠르게 컨텍스트를 잡을 수 있게 만드는 일입니다. 문서의 가치가 달라진 셈이죠.

의도와 실행이 분리됐다

요약하면 사람은 ‘의도와 판단’을, AI는 ‘실행과 정리’를 담당하는 구조였습니다.

기존 개발 방식과 비교해 보면 분담의 형태가 다릅니다. 예전에는 What, How, Verify를 모두 사람이 직접 수행했습니다. 의도를 정하는 일과 코드를 짜는 일, 검증과 문서화까지 같은 사람이 직접 했기 때문에, 참여한 사람의 수나 능력에 따라 일의 진행속도와 완성도가 달라졌고, 사람은 선택과 집중을 하기가 어려웠습니다.

이제는 AI가 How와 Verify의 작업들을 가져가면서, 사람의 일이 What과 판단으로 좁혀졌습니다. 그리고, 중요한 점은 코드 타이핑보다 What을 정하는 일이 작업의 핵심이었다는 사실입니다.


생산성 변화

생산성 측면에서는 예상대로 체감 차이가 꽤 컸습니다. 특히 ‘맥락 전환 비용’이 거의 사라졌다는 느낌이 강했습니다.

세부 작업을 보면, 소스코드 구현 외에 CSS 수정, Firebase 설정, 문서 정리, 테스트 케이스 작성, 배포, PR 생성 등이 각각 별도의 작업입니다. 이전 같으면, 각각 다른 도구, 다른 문법, 다른 머리를 써야 했습니다.

AI를 이용한 코딩에서는 ‘문제 → 대화 → 수정 → 배포 → 문서화’가 거의 하나의 흐름처럼 이어졌습니다. 특히 UI 나 직관적인 화면 동작 수정 속도는 거의 실시간에 가까웠습니다.

제 경험에 따르면, 영역에 따라 체감되는 속도 개선은 다릅니다.

  • 프로토타이핑: 5~10배 이상
  • 문서화 비용: 10배 이상
  • UI 반복 수정: 거의 실시간

특히 문서화 비용 감소가 컸습니다. README, RELEASE_NOTES, TEST_CASES 같은 문서들은 보통 프로젝트 주기에 맞춰서 겨우 작성하는 게 일반적인데, 이번에는 코드를 수정할 때마다 자연스럽게 업데이트 됐습니다.

종합하면 체감 생산성은 10~20배 수준이라고 생각합니다. 실제 작업 기간은 3일이었습니다. 같은 결과물을 혼자 학습하면서 만들었다면, React 흐름과 Firebase 연결에 며칠, OAuth 트러블슈팅과 Firestore Security Rules 학습에 며칠, 모바일 반응형 디테일에 며칠, 마이그레이션 스크립트와 문서화까지, 대략 한두 달짜리 프로젝트는 될 것 같습니다.

다만 이 수치는 단순히 코드 타이핑 속도가 아니라 모르는 영역을 최소한의 학습만으로 통과한 효과가 더 컸습니다. 제가 직접 했다면 학습하고 구현하느라 며칠씩 걸렸을 작업들이지만, AI가 만들어 준 코드를 검증하는 데에만 시간을 쓰면 됐습니다.


더 중요해진 것들

AI 때문에 오히려 더 중요해진 것들이 있었습니다. 이번 경험을 바탕으로, 다음에 비슷한 작업을 다시 한다면 처음부터 따르고 싶은 네 가지 원칙을 정리해 보았습니다.

① 꼭 필요한 스펙을 구분하고 먼저 작성한다

모든 스펙을 미리 다 정하고 시작하는 것은 현실적으로도 어렵고, AI를 활용한 코딩의 빠른 흐름상 비효율적입니다. 나중에 변경 비용이 비싼 요구사항과 그렇지 않은 것들을 잘 구분하고, 비용이 많이 드는 요구사항들에 대해서는 미리 결정하고 시작하는 것이 좋습니다. AI가 추측하지 않아야 할 결정을 먼저 명시하는 것도 중요합니다.

② Do와 Don’t를 명시적으로 정리한다

AI는 일반적으로 대량의 데이터로부터 학습한 일반적인 패턴을 선택합니다. 다만 그 패턴이 구현하고자 하는 결과물의 방향과 맞지 않을 수 있습니다. 어떤 패턴이 맞지 않는지 미리 명시해 두면, AI가 해당 패턴을 선택하는 것을 줄일 수 있습니다. AI에게 자유를 주기 전에 경계를 먼저 그어두는 것입니다.

③ 검증 방법을 먼저 정한다

만들어진 결과물을 평가할 수단이 없으면 품질 판단이 불가능합니다. 시드 데이터, 테스트 케이스, 체크리스트 같은 검증 수단을 시작 시점에 함께 준비해 두면, 만들면서 동시에 평가할 수 있습니다. 만든 뒤에 평가 수단을 찾기 시작하면 이미 늦습니다.

④ 개발 환경을 처음부터 잘 구축한다

자동화된 빌드/검증/배포 환경, AI 세션 시작 시 문서를 자동으로 읽히는 워크플로우 같은 것들을 초반에 갖춰두면, 검증 부담을 최대한 자동화할 수 있습니다. 사람은 판단과 적극적 피드백에 집중하고, 빌드/검증/배포는 최대한 자동화를 합니다.

이 네 가지를 다시 보면 결국 한 가지를 가리킵니다. AI에게 일을 시키기 전에, AI가 작업할 환경, 결과를 평가할 수 있는 환경을 먼저 만들어야 한다는 원칙입니다. 스펙은 비교 기준이 되고, Do/Don’t는 결과의 경계를 정하고, 검증 방법은 평가를 가능하게 하고, 개발 환경은 그 평가를 자동화합니다.

이렇게 정리해놓고 보니, 결국 하네스(harness) 엔지니어링이 중요하다는 결론이 되는 것 같습니다. 결국 AI 시대의 개발은 코드를 잘 짜는 것보다, AI를 둘러싼 하네스를 잘 설계하는 일에 가까워지고 있는 듯합니다.


맺음말

이번 경험에서 가장 크게 느낀 것은, AI는 개발자의 일을 없애기보다 개발의 병목을 이동시키고 있다는 점이었습니다. 코드를 직접 작성하는 시간이 줄어든 대신 방향을 정하고, 구조를 판단하고, 맥락을 관리하고, 결과를 검증하는 일이 훨씬 중요해졌습니다.

이번 작업의 결과가 좋았던 것은 물론 AI의 능력 덕분이 큽니다. 하지만, 더 중요한 것은 AI와 지속적으로 대화하면서 끊임없이 결과를 의심하고 검증하는 과정을 반복했다는 점입니다. 그게 가능했던 이유는 제가 가진 어느 정도의 전문성과 다양한 개발 경험을 바탕으로 AI를 리드했기 때문입니다.

결국 바이브 코딩이 작동하는 조건은 분명합니다. 사람은 의도(What)를 설계하고 AI는 구현(How)의 속도를 극단적으로 끌어올리는 협업 구조, 그리고 사람이 결과물을 평가할 수 있어야 합니다. 평가 역량이 없으면 협업이 아니라 위임이 되고, 위임의 결과는 운에 맡겨질 뿐입니다.

개발자는 강력한 도구를 얻었습니다. 다만 그 도구의 강력함은 사용자의 전문성에 비례합니다.
AI가 만든 코드의 옳고 그름을 판별할 수 있는 사람에게만, AI는 진짜 도구가 됩니다.

결국 좋은 도구는, 좋은 장인의 손에서만 좋은 결과를 만듭니다.

ChulJoo Kim (김철주).

ckarch.kr © 2026 is licensed under CC BY-NC-SA 4.0 CC BY NC SA

댓글 남기기