기획자가 직접 사용하기 위해 AI와 함께 개발한, 식습관 개선 목적의 식단 기록 앱
| 프론트엔드 | Vanilla JS → React 19 (JavaScript), Vite |
|---|---|
| 스타일 | CSS → Tailwind CSS |
| 상태 관리 | Zustand |
| 백엔드/DB | Firebase (Firestore) |
| 배포 |
나이 앞자리가 3으로 바뀌면서 몸이 예전 같지 않음을 느낀다. 뭘 먹어도 살이 붙는 건 둘째치고, 피부가 뒤집어지거나 역류성 식도염으로 고생하는 날이 잦아졌다.
밀가루를 줄여야 하나? 몇 시에 밥을 먹고 자야 다음 날 속이 안 아플까?
내 몸의 패턴을 분석해 보고자 야심차게 노션 데이터베이스를 만들어 식단 기록을 시작했다. 하지만 앱을 켜고, 페이지를 찾아 들어가 텍스트를 입력하기까지의 Depth가 너무 깊었다. 텍스트 위주다 보니 한눈에 들어오는 식별성도 떨어져 패턴을 읽어내는 데 큰 도움이 되지 않았고, 결국 한두 달을 넘기지 못하고 흐지부지 끝나버렸다.
그러던 중, 최근 Codex와 Claude Code 등을 활용한 바이브코딩이 일상화되면서 문득 이런 생각이 들었다.
‘노션 기록조차 귀찮은 나를 위한 맞춤형 앱, 이제는 직접 만들 수 있지 않을까?’
그렇게 오직 나를 위해 기획하고, AI와 함께 개발해 완성한 식습관 트래커 앱 끼니록의 탄생기를 공유해 본다.
시중에 수많은 식단 관리 앱이 있지만, 대부분 칼로리 계산이나 체중 감량 등 뚜렷한 목표 달성에 초점이 맞춰져 있었다. 사진을 찍으면 AI가 영양소를 분석해 주거나, 방대한 데이터베이스에서 내가 먹은 메뉴를 직접 검색해 입력하는 등 훌륭한 기능들이 많았지만 내게는 그 모든 과정이 그저 귀찮은 일에 불과했다.
내가 진짜 원했던 것은 어떠한 강박 없이, 무엇을 먹었는지와 먹고 나서 상태가 어땠는지를 가볍게 남기는 것이었다. 식후에 속이 쓰리거나 더부룩할 때 나중에 그 원인을 추적하고 회고할 수 있는 최소한의 데이터, 그리고 ‘채소 챙겨 먹기’나 ‘천천히 먹기’ 같은 좋은 식습관이 잘 유지되고 있는지 보여주는 직관적인 지표면 충분했다.
이 모든 것을 충족하기 위한 절대적인 전제 조건은 귀찮지 않아야 한다는 것이었다. 앱을 켜고 기록을 완료하기까지의 Depth를 최소화하여, 사용자가 지치지 않고 꾸준히 입력할 수 있는 환경을 만드는 것을 이번 프로젝트의 핵심 과제로 정의했다.
기록 부담 없는 식습관 트래커라는 콘셉트에 맞춰, 프로덕트 전체를 관통하는 정체성과 비주얼 방향성을 먼저 정립했다.
화면 또한 복잡한 Depth는 모두 걷어내고 기록과 회고의 흐름에 따라 6개의 주요 화면으로 구성했으며, 하단 내비게이션 바 역시 [홈 / 추가 / 요약] 딱 3가지만 배치했다.
서비스명인 끼니록은 유사 서비스와 겹치지 않으면서도 서비스의 본질을 직관적으로 드러내는 이름이다. ‘식단’이라는 단어가 주는 딱딱함과 강박을 지우고 싶어 ‘끼니’라는 친근한 단어를 선택했다. 끼니록의 ‘록’은 기록할 록(錄)이자 하루의 일지(Log)를 뜻하는 중의적 표현으로, 입에 착 붙는 발음까지 고려한 결과물이다.
절대 강압적이지 않고 다정한 분위기를 지향한다. 음식 관련 서비스인 만큼 노란색과 초록색을 두고 고민하다가, 건강한 습관을 상징하는 초록색을 메인 컬러로 낙점했다. 인터페이스와 버튼 등 전반적인 비주얼 요소는 둥글둥글하고 포근한 느낌으로 설계해 심리적 허들을 낮췄다.
'끼니록'이라는 이름의 어감에서 자연스럽게 연상되는 귀여운 토끼를 마스코트로 삼았다. 맛있는 음식을 품에 소중히 들고 있는 토끼의 모습을 앱의 시그니처 아이콘으로 배치해, 유저가 앱을 켤 때마다 기분 좋은 친근감을 느낄 수 있도록 위트를 더했다.
하루 단위의 정보만 깔끔하게 보여주는 대시보드다. 좌우로 스와이프하여 날짜를 쉽게 넘길 수 있다.
아침에 일어났을 때 속이 불편한 경우가 많아, 내 상태를 추적하기 위해 만든 기능이다. 사용자가 설정한 하루 시작 시간이 지난 후 앱을 켜면 컨디션을 묻는 바텀시트가 표시된다. 여기서 선택한 [좋음/보통/나쁨] 상태는 홈 화면과 주간 요약 화면에서 확인할 수 있다.
| 오늘의 인사이트 | 오늘의 기록 | |
|---|---|---|
| 위치 | 홈 화면 상단 | 홈 화면 하단 |
| 역할 | 식단 입력 시 누적된 태그를 분석하고, 내부 스코어 로직을 통해 도출된 한 줄 문구 출력 | 하루 동안 어떤 태그가 입력되었는지 요약본 형태로 표시 |
실제로 여러 식단을 입력해 보며 현재 가장 유심히 지켜보고 있는 영역이다.
한 끼에 여러 개의 메뉴를 먹었을 때 UI가 지저분해지는 걸 막기 위해 아래와 같은 방법으로 깔끔함을 유지했다.
[메뉴] 외 2가지와 같은 형태로 축약내비 바 가운데 플로팅 된 [+(추가)] 버튼을 누르면 진입한다. 칼로리나 g(그램) 수를 계산하는 스트레스를 없애고, 오직 버튼 탭만으로 식사 상태를 구조화할 수 있도록 했다.
텍스트만으로는 부족한 식단 기록을 보완하기 위해 사진 첨부 기능을 넣었다. 한 끼당 최대 5장까지 첨부 가능하며, 편집 아이콘을 통해 사진 변경 및 삭제가 자유롭게 이루어진다.
데이터 정합성 유지 차원에서 [아침/점심/저녁]은 하루에 한 번만 등록할 수 있게 막았다. 반면 간식과 음료는 무제한 등록 가능하며, 시간 입력은 선택 옵션으로 두어 기록에 대한 강박을 줄였다.
숫자를 대신하는 이 앱의 정체성이자 핵심 데이터다. 실사용 중 필요성을 느낄 때마다 유연하게 항목을 추가하고 있다.
| 줄이기 | 밀가루, 당(설탕), 기름짐, 매움, 나트륨(염분), 술 |
|---|---|
| 챙기기 | 채소, 단백질, 과일 |
| 식사 상황 | 야식, 배달/외식, 집밥 |
| 먹고 나서 | 속 편함, 졸림, 더부룩함, 속쓰림, 배아픔 |
| 탄수화물 양 | 없음, 적게, 보통, 많이 |
| 포만감 |
현재 홈 화면의 한 줄 인사이트는 태그마다 점수를 매겨 우선순위를 판단하는 로직을 거쳐 출력된다.
초기엔 단순한 If/Else문을 썼지만, ‘속쓰림’(건강 적신호)이 ‘빠른 식사’(행동 경고) 조건에 밀려 노출되지 않는 우선순위 오류가 있었다. 이를 해결하기 위해 모든 태그에 점수를 부여했다.
불편 신호: 500~699점 > 행동 경고: 230~430점 > 긍정 신호: 80~200점사용자는 그저 태그를 누를 뿐이지만, 시스템은 백그라운드에서 가장 점수가 높은(=가장 시급하게 알림을 줘야 하는) 상태를 계산해 피드백을 건넨다.
다만, 태그가 많아질수록 정확도가 떨어지는 경향이 있어 일정 기간 테스트 후 더 나은 방식으로 보완할 예정이다.
홈 화면에서 입력된 끼니 카드 선택 시 진입한다. 기존 기록 화면과 거의 유사한 UI로 구성하여, 진입 즉시 직관적인 수정이 가능하도록 유연한 편집 UX를 제공한다.
자주 먹는 고정 식단(예: 닭가슴살 샐러드 등)을 즐겨찾기로 등록할 수 있다. 등록해 둔 식단은 새로운 끼니를 입력할 때 상단에서 클릭 한 번으로 똑같은 메뉴와 태그셋을 그대로 불러올 수 있어, 매번 입력해야 하는 번거로움을 획기적으로 줄여준다.
입력만 하고 끝난다면 과거 노션에 적던 시절과 다를 바 없다. 요약 탭은 월요일부터 일요일까지 한 주간의 식습관을 돌아보는 회고의 공간이다.
| 주간 인사이트 | 매일 보던 ‘오늘의 인사이트’를 주 단위로 확장하여 종합적인 분석 멘트를 제공한다. |
|---|---|
| 주간 요약 | 특정 태그가 총 몇 번 입력되었는지 최대 6개 항목까지 보여준다. *현재는 고정된 항목만 표시되고 있어, 사용자가 원하는 태그만 볼 수 있도록 커스텀 기능 수정 중 |
| 자주 나온 태그 | 이번 주에 가장 많이 입력된 태그를 TOP1부터 TOP5까지 내림차순으로 보여준다. |
| 하이라이트 | 앱이 유도하는 긍정 행동이나 빈번하게 발생한 ‘줄이기’ 태그의 횟수를 짚어준다. *다만 현재 로직의 실효성에 의문이 있어 주간 요약 기능과 함께 개편 계획 중 |
일주일 동안 아침 컨디션이 어땠는지 날짜와 아이콘 모음으로 한 번에 모아볼 수 있다.
이미지에 첨부한 5월 마지막 주는 유독 두드러기가 심하고 속이 안 좋았던 주간인데, 이 데이터 덕분에 내 상태와 식단의 상관관계를 파악하는 데 큰 도움이 되었다.
가벼운 키워드들이 쌓여 만들어진 일종의 식단 DB를 가볍게 탐색하고 추적할 수 있는 공간이다.
검색창에 계란, 닭발 등 이전에 먹었던 끼니명을 입력하면, 과거에 그 음식을 먹었던 날짜와 당시의 끼니 카드가 매칭되어 일렬로 표시된다.
과거 기록을 찾기 쉽도록 [최신순 / 오래된 순] 정렬 기능을 제공한다. 특정 음식을 먹었을 때 컨디션이나 애프터 태그(더부룩함, 속쓰림 등)가 어땠는지 히스토리를 빠르게 역추적해 볼 수 있는 미니멀한 검색 창고 역할을 한다.
사용자의 생활 패턴에 맞춘 상세 설정과 안심하고 사용할 수 있는 클라우드 연동 정책을 담은 화면이다.
요약 탭에 보고 싶은 항목을 최대 5개까지 선택해 노출할 수 있다.
*일부 싱크가 맞지 않는 현상이 있어 현재 로직 확인 및 수정 중
또한, 내가 등록한 즐겨찾기 리스트를 한눈에 보고 관리할 수 있는 가벼운 어드민 영역을 포함한다.
자정이 지났다고 해서 무조건 날짜가 바뀌는 방식은 새벽에 야식을 먹거나 늦게 잠드는 등 다양한 라이프스타일을 반영하기 어려웠다. 이를 해결하기 위해 사용자가 직접 하루 시작 시간을 정의할 수 있도록 했다.
하루 시작 시간을 오전 6시로 설정해 두면, 자정이 넘어 새벽 2시에 음식을 기록하더라도 앱은 다음 날로 넘어가지 않고 이전 날짜의 기록 화면을 그대로 유지한다. 기계적인 시간이 아닌, 실제 사용자의 생활 주기에 맞춰 데이터의 정합성을 확보하기 위함이다. 아침 컨디션을 확인하는 바텀시트 역시 이 시간 이후 앱을 처음 열 때 자동으로 표시된다.
브라우저 캐시를 초기화하거나 기기를 변경하면 데이터가 날아가는 PWA의 단점을 해결하기 위해 Firebase Firestore 기반의 구글 계정 연동 기능을 도입했다.
특히, 비로그인 상태로 모은 로컬 데이터(LocalStorage 및 IndexDB에 저장된 내역)가 로그인하는 순간 클라우드 데이터와 안정적으로 병합되도록 동기화 방식을 구축했다.
서버 연동은 이번 프로젝트에서 처음 시도해 보았는데, 트래픽과 용량을 고려했을 때 Firebase 무료 버전으로도 충분히 커버가 가능했다. 서버 연결부터 로그인 연동까지, 이래도 되나 싶을 정도로 빠르고 매끄럽게 진행되어 기술적으로도 아주 만족스러웠다.
초기 앱은 지금보다 훨씬 더 원초적인, MVP의 MVP 수준이었다. 프로덕트를 혼자 만들어 사용할 때의 가장 큰 장점은 내가 곧 기획자이자 최종 소비자라는 점이다. 복잡한 TC나 별도의 QA 프로세스가 없어도, 매일 밥을 먹고 직접 앱에 기록하는 행위 자체가 가장 확실한 QA였다.
사진 추가, 구글 로그인 연동, 검색 기능 같은 것도 처음부터 기획에 넣었던 건 아니었다. 앱을 쓰다 보니 자연스럽게 사진도 넣고 싶고, 검색도 하고 싶은 니즈가 생겼다. 필요한 기능은 유동적으로 덧붙이고, 불필요한 기능은 과감히 쳐내며 프로덕트를 다듬어 나가고 있다.
디자인을 고도화하기 위해 스타일 코드를 뜯어 보던 중 이상한 점을 발견했다. 분명 프롬프트로 Tailwind CSS 사용을 지시했는데, 실제 코드는 Tailwind가 전혀 적용되지 않는 바닐라 JavaScript 기반으로 작성되어 있었다. 어쩐지 이전 프로젝트들과 기능 구현 방식이나 디자인 커스텀이 미묘하게 달랐다.
개발 초기에 AI와 대화하며 언어 및 프레임워크 셋업을 정확하게 지시하지 않았던 것이 화근이었다. AI가 초반에 가장 빠르게 구현할 수 있는 단일 파일 구조의 바닐라 JS로 코드를 빌드해 버린 것이다.
확장성과 디자인 컴포넌트화를 위해 React 19 + Tailwind CSS 조합으로 전면 리팩토링을 단행했다. Claude Code 덕분에 전환 자체는 빠르게 진행되었지만, 이 과정에서 기존에 잡아두었던 미세한 UI 디테일이나 기능 정책들이 일부 유실되었다.
결국 기능과 화면을 하나씩 다시 검수하며 싱크를 맞춰야 했다. 바이브코딩에서도 초기 아키텍처 정의가 중요하다는 사실을 몸소 체감했다.
초기에는 데스크톱 브라우저로만 테스트를 하다가 모바일에서도 기록을 시작했다. 기기를 번갈아 사용하다 보니 동기화가 되지 않는 점이 불편했고, 브라우저 캐시가 날아가면 데이터도 함께 사라질 수 있다는 불안감이 생겨 구글 로그인을 연동했다.
그런데 로그인 버튼을 누르는 순간, 휴대폰 로컬에 며칠간 쌓아 두었던 소중한 식단 기록이 클라우드의 빈 데이터에 덮어 씌워지며 순식간에 증발해 버렸다. 비로그인 상태의 로컬 데이터와 구글 로그인 이후의 클라우드 데이터 간 병합 정책을 미리 세워두지 않아 발생한 충돌이었다.
부랴부랴 소 잃고 외양간 고치는 심정으로 데이터 동기화 정책을 재정비했다. 로그인 성공 시, 무조건 클라우드 데이터를 덮어쓰는 것이 아니라 mealDate를 기준으로 더 최근에 기록된 데이터를 비교하여 유실 없이 병합되도록 로직을 수정했다.
초기 디자인은 눈 뜨고 보기 힘든 와이어프레임에 가까웠다. 게다가 촌스러운 초록색이 앱 전체를 뒤덮고 있어 완성도가 상당히 처참했다. 프로젝트를 진행할 때마다 느끼지만, 아무리 AI가 유능해도 미감과 감성의 영역까지 완전히 맡기기는 어렵다.
그래서 레퍼런스를 최대한 구체적으로 제시했다.
“토스 UI/UX처럼 깔끔하게 컴팩트하게 만들어 줘!”
이런 식의 가이드를 주며 AI의 디자인 싱크를 계속해서 끌어올렸다. 그 결과 이전보다 훨씬 나은 결과물을 얻을 수 있었지만, 여전히 100% 마음에 들지는 않는다.
조만간 폰트와 컬러 시스템을 포함한 디자인 전반을 대대적으로 갈아엎을 예정이다. AI가 디자인을 대신해 주는 시대가 왔다고는 하지만, 결국 마지막 디렉팅과 취향의 판단은 사람의 몫이라는 사실을 다시금 느꼈다.
아직 혼자 사용하는 앱이다 보니 다운로드 수나 DAU 같은 거창한 정량적 지표를 성과로 내세울 수는 없다. 하지만 프로덕트를 직접 배포하고 일상에서 유지보수하며 운영 단계까지 끌고 간 경험은 그 어떤 사이드 프로젝트보다 값진 성과를 남기고 있다.
이번 프로젝트에서 가장 만족스러운 정성적 성과 중 하나는 UX 라이팅을 시스템화했다는 점이다. 개발 초반부터 앱 내에 들어가는 멘트와 안내 문구들을 별도의 마크다운 파일인 copy.md로 분리해 관리했다. 카피의 수정 히스토리까지 축적하며 관리한 덕분에 무거운 코드를 일일이 뒤지지 않고도 전체 서비스의 톤앤매너를 일관되게 유지하고 빠르게 검수할 수 있었다. 실무에서 UX 라이팅을 어떻게 관리하면 좋을지 프로세스를 만들어 본 좋은 경험이었다.
또한 앱을 통해 식습관 개선 효과를 톡톡히 보고 있다. 거창한 빅데이터가 쌓인 건 아니지만 매일 직접 끼니를 기록하면서 몸의 변화를 추적하는 데 실질적인 도움이 된다! 아침에 속이 아플 때 전날 기록을 역추적하며 원인을 직관적으로 인지하게 되니, 자연스럽게 식습관을 조절하게 되었다. 사용자 관점에서의 프로덕트 효용성을 기획자가 스스로 검증해 낸 셈이다.
혼자서 기획을 주도하고 AI와 끊임없이 타협하며 결과물을 만들어내는 과정 자체가 거대한 레슨런이기도 했다. 내가 가진 기획 아이디어를 점수제 같은 개발 로직으로 치환하기 위해 프롬프트를 다듬고, 기술적 한계와 합의점을 찾는 과정 속에서 개발 프로세스에 대한 이해도가 한층 깊어졌다.
아이데이션부터 기획, 디자인 가이드, AI를 통한 개발, 그리고 출시 후 실제 데일리 유저로서 버그를 잡고 개선 사항을 뽑아내는 일련의 플로우를 모두 경험할 수 있었다. 이렇게 작게나마 프로덕트의 전체 생애 주기를 A부터 Z까지 운영해 본 경험은 나중에 개발자 및 디자이너와 협업할 때 프로덕트의 맥락을 넓고 확실하게 짚어낼 수 있는 단단한 밑거름이 될 것이라 확신한다.
물론 앞으로 해결해야 할 과제도 많다. 현재의 스코어 제도도 훌륭한 대안이지만, 데이터와 태그가 더 촘촘하게 쌓일수록 정확도가 미흡해지는 듯하다. 나에게 딱 맞는 정밀한 패턴 분석 기능을 위해 가중치 산정 방식을 더 정교하게 다듬어서 파고들 생각이다.
지금은 나 혼자 사용하며 1인 QA를 진행하고 있지만 조금 더 룰베이스를 고도화하고 디자인 시스템을 보완해서 정식 배포까지 도전해 보고 싶다. 칼로리 계산에 지쳐 식습관 회고를 포기했던 많은 사람들에게 이 부담 없는 서비스를 당당하게 선보일 날을 기대한다😊
| 먹는 속도 | 모르겠음, 20분 이내, 30~50분 이내, 1시간 이상 |
|---|
저녁 및 간식일 경우 식사 상황에 야식이 추가된다.
| 줄이기 | 당(설탕), 카페인, 탄산 |
|---|---|
| 챙기기 | 물 |
| 먹고 나서 | 속 편함, 졸림, 더부룩함, 속쓰림, 배아픔 |
| 포만감 | 배고픔만 겨우 채움, 가볍게 먹음, 적당함, 적당에서 약간 배부름, 배 터질 것 같음 |