🛠️
개발 이야기 ⏱ 8분 📅 2026.05.21

직장인 점심뭐먹지 개발기

AI와 함께 0원으로 PWA를 만든 이야기
100+ 메뉴 데이터, 룰렛 추첨, 다크모드, 날씨 연동까지

📋 목차

  1. 서비스 소개 — 왜 만들었나요?
  2. 기술 스택 — 0원으로 만든 방법
  3. 주요 기능 개발 과정
  4. 개발하면서 어려웠던 점
  5. Claude AI와 협업한 경험
  6. 앞으로 추가할 기능
💡

서비스 소개 — 왜 만들었나요?

"오늘 점심 뭐 먹지?" — 이 질문은 매일 반복되지만 답을 내리기가 여간 어렵지 않습니다. 메뉴는 수십 가지인데 막상 고르려면 아무것도 떠오르지 않고, 팀원들의 취향도 제각각이라 결정 장애가 생기기 마련입니다.

저 역시 매일 12시가 되면 "오늘은 뭐 먹지?"로 10분을 낭비하고 있었습니다. 그러다 문득 생각했습니다. "직장인 점심 메뉴 추천 서비스를 만들면 어떨까?"

🎯 서비스 목표

  • 메뉴 결정에 쓰는 시간을 줄이고 점심을 즐겁게 만들기
  • 기분·상황·식비·식단 필터로 딱 맞는 메뉴 추천
  • 룰렛 추첨으로 결정을 재미있는 이벤트로 전환
  • 블로그와 가이드로 직장인 점심 정보 허브 구축
  • 별도 비용 없이 운영 가능한 서비스 만들기

그렇게 jikjang.vercel.app이 탄생했습니다. 서버 비용 0원, 개발 비용 0원, 하지만 기능은 꽉 채운 PWA 서비스입니다.

⚙️ 기술 스택 카드 — 모두 무료 도구만 사용
🌐
HTML5
시맨틱 마크업, SEO 최적화, Schema.org 구조화 데이터
정적 사이트
🎨
CSS3
CSS 변수로 다크모드, Grid·Flexbox 레이아웃, 애니메이션
스타일링
Vanilla JS
프레임워크 없이 순수 JS. 번들러·빌드 도구 없이 바로 배포
No Framework
📱
PWA
manifest.json + Service Worker로 앱처럼 설치 가능, 오프라인 지원
앱화
🔧
Service Worker
캐시 전략(Cache First)으로 오프라인 동작, 빠른 로딩
오프라인
🚀
Vercel
GitHub 연동 자동 배포, 무료 SSL, CDN, 도메인 제공
무료 배포

모든 기술 스택이 무료 — 월 운영 비용 0원

🏗️

왜 정적 사이트를 선택했나?

Next.js, React 같은 프레임워크를 쓸 수도 있었습니다. 하지만 정적 HTML/CSS/JS를 선택한 이유가 있습니다.

정적 사이트의 장점

  • 배포가 가장 단순: 빌드 단계 없이 파일 그대로 업로드. GitHub Push → 즉시 배포.
  • SEO 최적화 유리: SSR/SSG 설정 불필요. HTML이 곧 완성된 페이지.
  • 학습 비용 제로: 누구나 읽고 수정할 수 있는 표준 웹 기술.
  • 서버 비용 없음: Vercel 무료 플랜으로 글로벌 CDN 배포 가능.
  • 빠른 로딩: JavaScript 번들 없이 HTML 파일 하나로 즉시 렌더링.

PWA로 Service Worker까지 추가하니 오프라인에서도 동작하고, 홈 화면에 설치까지 됩니다. "0원짜리 앱"이 완성된 순간이었습니다.

📅 기능 개발 타임라인 — 주요 기능 구현 흐름
1
🍽️ 메뉴 데이터베이스 구축
Phase 1
100+ 메뉴를 JSON으로 정리. 카테고리(한식·중식·일식·양식·분식), 가격대, 칼로리, 기분 태그, 날씨 태그 등 다중 속성으로 구조화.
2
🔍 다중 필터 추천 로직
Phase 2
기분·식비·식단·날씨 필터를 AND 조건으로 조합. 필터 결과가 없으면 조건을 완화하는 fallback 로직 추가로 항상 결과 보장.
3
🎰 룰렛 추첨 시스템
Phase 3
Canvas 기반 원형 룰렛으로 시작 → CSS 3D 드럼 롤 방식으로 진화. 모바일에서 Canvas 성능 이슈를 해결하고 더 세련된 UX 완성.
4
🌙 다크모드 & 야간모드
Phase 4
CSS 변수(--text, --bg, --border 등)로 전체 테마 시스템 구축. localStorage로 설정 저장, 시스템 다크모드 감지(prefers-color-scheme)도 지원.
5
🌤️ 날씨 연동 & 현위치 지도
Phase 5
OpenWeatherMap API로 현재 날씨 연동 → 날씨 맞춤 메뉴 추천. Geolocation API + Kakao Maps로 현위치 기반 주변 식당 지도 구현.
6
📝 블로그 & SEO 최적화
Phase 6
20+ 포스트 발행, Schema.org JSON-LD 구조화 데이터, Open Graph, sitemap.xml, robots.txt, 읽기 진행 바까지 SEO 완전 최적화.
7
📱 PWA & Service Worker
Phase 7
manifest.json으로 홈 화면 설치 지원, Service Worker로 Cache First 전략 적용. 오프라인 메뉴 추천까지 가능한 완전한 PWA 완성.
🎲

룰렛 추첨: Canvas에서 CSS 3D로

처음에는 Canvas API로 원형 룰렛을 그렸습니다. 데스크톱에서는 잘 돌아갔지만, 모바일에서 애니메이션이 뚝뚝 끊기는 문제가 생겼습니다. 특히 저사양 안드로이드 기기에서 Canvas 렌더링이 버벅거렸고, requestAnimationFrame 루프가 배터리를 과도하게 소모했습니다.

💬 Claude AI와 함께 해결한 과정

Canvas 성능 문제를 Claude에게 설명했더니, CSS 3D transform을 활용한 드럼 롤 방식을 제안해줬습니다. perspective와 rotateX를 이용해 세로 방향으로 메뉴가 회전하는 드럼 롤 UI를 CSS 애니메이션만으로 구현했습니다.

"CSS 3D 애니메이션은 GPU 합성 레이어로 처리되어 CPU 부담이 없고, 모바일에서도 60fps를 유지합니다. will-change: transform을 추가해 미리 레이어를 준비하면 더욱 부드러워집니다."

결과적으로 CSS 3D 드럼 롤 방식이 훨씬 부드럽고 에너지 효율도 좋았습니다. 코드 양도 오히려 줄었습니다.

🌤️

날씨 연동과 현위치 기반 지도

날씨에 따라 먹고 싶은 음식이 달라집니다. 비 오는 날엔 파전과 막걸리, 더운 날엔 냉면과 아이스크림이 생각나죠. 이 아이디어를 실제 기능으로 만들었습니다.

🌡️ 날씨 연동 메뉴 추천 로직

  • 맑음 & 고온(25°C+): 냉면, 콩국수, 냉모밀, 아이스크림 가중치 상승
  • 비 & 흐림: 파전, 칼국수, 순댓국, 뜨거운 국물 요리 가중치 상승
  • 저온(10°C 미만): 찌개류, 탕류, 전골 가중치 상승
  • API 실패 시: 날씨 필터 비활성화, 나머지 필터로 추천 계속

현위치 기반 지도는 Geolocation API로 현재 좌표를 얻은 뒤 Kakao Maps SDK로 주변 식당을 표시합니다. 위치 권한을 거부해도 지도 없이 메뉴 추천은 정상 동작하도록 graceful degradation을 적용했습니다.

😅

개발하면서 어려웠던 점

📦
모바일 Service Worker 캐시 문제
코드를 수정해도 사용자 기기에 이전 버전이 캐시되어 업데이트가 반영되지 않는 문제가 가장 골치 아팠습니다. 특히 iOS Safari에서는 Service Worker 업데이트 동작이 Chrome과 달라서 구버전이 계속 서빙되는 경우가 생겼습니다.
해결책: 캐시 버전 키(CACHE_VERSION)를 배포마다 갱신하고, skipWaiting() + clients.claim()으로 즉시 활성화. 업데이트 감지 시 사용자에게 새로고침 안내 토스트 표시.
🌙
다크모드 CSS 변수 일관성 유지
페이지가 늘어날수록 다크모드에서 일부 요소가 어색하게 보이는 경우가 생겼습니다. 하드코딩된 색상 값(#FFFFFF, #000000 등)이 섞여 있어 다크모드 토글 시 색이 뒤집히지 않는 부분이 발생했습니다.
해결책: 모든 색상을 CSS 변수로 추출(--bg, --surface, --text, --muted, --border). body.dark 클래스에 변수를 재정의하는 방식으로 일관성 확보.
📱
모바일 애니메이션 성능
룰렛 애니메이션, 카드 전환 효과 등이 저사양 모바일에서 버벅거렸습니다. JavaScript로 직접 DOM을 조작하는 애니메이션은 메인 스레드를 블로킹해 60fps를 유지하기 어려웠습니다.
해결책: CSS transform과 opacity만 사용(GPU 가속 속성). JavaScript 애니메이션을 CSS @keyframes로 전환. will-change 힌트로 미리 레이어 생성. 복잡한 애니메이션에 prefers-reduced-motion 지원 추가.
🔍
SEO와 정적 사이트의 균형
JavaScript로 동적으로 생성되는 콘텐츠는 검색 엔진이 제대로 인식하지 못하는 경우가 있었습니다. 특히 룰렛 결과나 필터링된 메뉴 목록은 크롤러에 노출되지 않았습니다.
해결책: 핵심 콘텐츠는 HTML에 직접 포함. 블로그/가이드 페이지는 완전한 정적 HTML로 제공. Schema.org JSON-LD로 구조화 데이터 삽입해 검색 결과 rich snippet 확보.
🤖

Claude AI와 협업한 경험

이 프로젝트의 거의 모든 코드는 Claude AI와 함께 작성했습니다. 단순히 코드를 생성받는 게 아니라, 문제를 함께 분석하고 해결책을 고민하는 파트너로 활용했습니다.

🤝 협업이 특히 효과적이었던 순간들

1. 메뉴 필터 로직 설계: "사용자가 필터를 많이 선택할수록 결과가 없어지는 문제"를 Claude에게 설명했더니 AND 조건을 완화하는 fallback 전략을 제안해줬습니다. 필터 수를 줄여가며 재시도하는 로직이 지금의 추천 시스템 핵심입니다.

2. CSS 3D 룰렛 구현: Canvas 성능 문제를 말했더니 perspective + rotateX를 이용한 드럼 롤 방식을 제안했고, 구체적인 CSS 코드까지 바로 작성해줬습니다.

3. Service Worker 캐시 전략: Stale-While-Revalidate, Cache First, Network First의 차이를 설명하고 각 리소스 유형별 최적 전략을 안내해줬습니다.

"AI를 쓴다고 개발자가 필요 없어지는 게 아니라, 혼자서는 며칠 걸릴 문제를 몇 시간 안에 해결할 수 있게 됩니다. 중요한 건 무엇을 만들지, 어떤 UX를 줄지 — 방향을 잡는 사람의 역할입니다."

Claude AI 효과적으로 활용하는 법

  • 문제를 구체적으로 설명: "버그가 있어요" 보다 "iOS Safari에서 다크모드 토글 후 배경색이 반영 안 됩니다"처럼 상세히.
  • 기존 코드 전체를 공유: 컨텍스트가 많을수록 더 정확한 답변이 나옵니다.
  • 왜 그런 선택을 했는지 물어보기: 코드만 받지 말고 설명도 요청해야 실력이 늘어납니다.
  • 대안을 물어보기: "다른 방법은 없나요?"로 더 좋은 접근법을 발견하는 경우가 많습니다.
  • 검증하기: AI 코드도 직접 테스트하고 이해해야 합니다. 맹목적 복붙은 나중에 더 큰 문제를 만듭니다.
🚀

앞으로 추가할 기능

서비스를 만들고 나면 아이디어는 오히려 더 많아집니다. 다음에 추가할 기능들을 정리했습니다.

🤖
AI 메뉴 추천
Claude API를 연동해 대화형으로 메뉴를 추천받는 챗봇 기능.
📊
개인 식사 기록
LocalStorage로 최근 먹은 메뉴를 기록하고 겹치지 않게 추천.
👥
팀 동시 추첨
QR코드로 팀원 모두가 동시에 참여하는 실시간 룰렛.
🗺️
식당 즐겨찾기
자주 가는 식당을 저장하고 거기서 메뉴를 추천받는 기능.
🏆
메뉴 평가 & 랭킹
사용자 반응을 모아 인기 메뉴 실시간 랭킹 표시.
📅
주간 식단 계획
일주일 점심 메뉴를 미리 계획하고 알림 받는 기능.

💬 피드백을 기다립니다

  • 사용하면서 불편한 점이 있으셨나요?
  • 추가됐으면 하는 메뉴가 있나요?
  • 기능 아이디어나 버그 제보도 환영합니다!
  • 서비스를 통해 점심 고민이 해결됐다면 주변에 공유해주세요 :)

직접 써보고 싶으신가요?

🛠️ 지금 바로 점심 메뉴를 추천받아보세요!

🍱 메뉴 추천 받으러 가기