Todo 앱 구축
Vibe Coding으로 나만의 Todo 앱을 단계별로 만들어봅니다. 처음 만들어보는 웹 프로젝트로 적합합니다.
프로젝트 개요
이 튜토리얼에서는 Vibe Coding을 활용하여 간단한 Todo 앱을 만들어봅니다. Todo 앱은 웹 개발의 기본기를 다지기에 가장 좋은 프로젝트입니다. CRUD(Create, Read, Update, Delete) 패턴을 자연스럽게 익힐 수 있고, 상태 관리와 데이터 영속화의 기본 개념까지 경험할 수 있습니다.
Todo 앱은 다음과 같은 기능을 포함합니다:
- 할 일 추가 및 입력 유효성 검사
- 할 일 완료/미완료 토글 표시
- 할 일 삭제 (확인 후 삭제)
- 할 일 수정 (인라인 편집)
- 필터링 (전체/진행중/완료)
- 로컬 저장소로 데이터 영속화
- 반응형 디자인 (모바일/태블릿/데스크톱)
- 다크 모드 지원
- 사용자가 입력한 할 일을 목록에 추가
- 체크박스로 완료 여부 표시
- 삭제 버튼으로 항목 제거
- 페이지를 새로고침해도 데이터 유지 (localStorage)
사용 기술 스택
| 기술 | 용도 | 비고 |
|---|---|---|
| HTML5 | 마크업 구조 | 시맨틱 태그 활용 |
| CSS3 | 스타일링 | Flexbox, CSS Variables, 트랜지션 |
| Vanilla JavaScript | 앱 로직 | ES6+ 문법, 모듈 패턴 |
| localStorage API | 데이터 영속화 | JSON 직렬화/역직렬화 |
React나 Vue 같은 프레임워크 없이 순수 JavaScript로 만드는 이유는 기본 원리를 이해하기 위해서입니다. DOM 조작, 이벤트 처리, 상태 관리의 기초를 직접 구현해보면, 이후 프레임워크를 사용할 때 내부 동작 원리를 더 잘 이해할 수 있습니다.
프로젝트 파일 구조
todo-app/
├── index.html # 메인 HTML 파일
├── css/
│ └── style.css # 스타일시트 (다크모드 포함)
├── js/
│ └── app.js # 앱 로직 (모듈 패턴)
└── README.md # 프로젝트 설명서
Step 1: 프로젝트 폴더 준비
먼저 프로젝트를 위한 폴더를 만들고 원하는 AI 코딩 도구를 실행합니다. 아래는 Claude CLI 예시입니다.
# 프로젝트 폴더 생성
mkdir todo-app
cd todo-app
# Git 초기화 (선택사항이지만 권장)
git init
# 예시: Claude CLI 실행
npx claude
AI가 코드를 생성하는 과정에서 여러 번 수정이 발생합니다. Git으로 버전 관리를 하면 각 단계의 변경 사항을 추적하고, 문제가 생겼을 때 이전 상태로 쉽게 되돌릴 수 있습니다. 각 기능 추가 단계마다 커밋하는 습관을 들이세요.
다른 AI 코딩 도구(Cursor, VS Code + Copilot, Windsurf 등)를 사용하는 경우에도 해당 폴더를 열어 동일한 방식으로 진행합니다.
Step 2: AI에게 앱 생성 요청
AI 도구에게 아래와 같이 요청하여 앱을 생성합니다. 핵심은 구체적이고 명확한 요구사항을 제시하는 것입니다.
초기 프롬프트 작성
만들고 싶은 것:
HTML, CSS, JavaScript로 된 간단한 Todo 앱을 만들어줘.
요구사항:
1. 할 일을 입력하는 입력창과 추가 버튼
2. 할 일 목록은 체크박스와 텍스트, 삭제 버튼이 포함
3. 체크박스를 누르면 완료 표시(취소선)
4. 삭제 버튼을 누르면 항목이 제거됨
5. localStorage에 데이터를 저장하여 새로고침해도 유지
6. 디자인은 깔끔하고 모던하게
기술 스택(사용할 언어/라이브러리), 기능 목록(번호 매겨 구체적으로), UI 요구사항(디자인 방향), 데이터 처리(저장 방식)를 포함하면 좋은 결과를 얻을 수 있습니다.
요구사항이 지나치게 많으면 AI가 일부를 놓칠 수 있습니다. 핵심 기능을 먼저 구현하고, 추가 기능은 단계적으로 요청하세요. 이것이 Vibe Coding의 점진적 개발(Incremental Development) 방식입니다.
Step 3: 생성된 코드 확인
AI 도구가 아래와 같은 파일들을 생성합니다:
index.html- 메인 HTML 파일 (시맨틱 구조)css/style.css- 스타일 시트 (반응형 + 다크모드)js/app.js- 자바스크립트 앱 로직
HTML 구조 요점
AI가 생성하는 HTML의 핵심 구조는 다음과 같습니다:
<header>: 앱 제목과 다크모드 토글 버튼<form>: 입력창(input[type=text])과 추가 버튼(button[type=submit])<div class="filters">: 전체/진행중/완료 필터 버튼 3개<ul id="todo-list">: JavaScript로 동적 생성되는 할 일 목록<footer>: 남은 할 일 개수와 완료 항목 일괄 삭제 버튼
CSS 핵심 패턴
CSS Variables로 라이트/다크 테마를 관리하고, 미디어 쿼리로 모바일 반응형을 구현합니다:
:root에 색상 변수 정의 (--bg-primary,--accent등)[data-theme="dark"]선택자로 다크 모드 색상 재정의.todo-item.completed .todo-text에text-decoration: line-through적용@media (max-width: 768px)로 모바일 레이아웃 조정
JavaScript 핵심 로직
아래는 전형적인 JavaScript 앱 로직의 예시입니다:
// 할 일 추가
function addTodo(text) {
const todo = {
id: Date.now(),
text: text,
completed: false
};
todos.push(todo);
saveTodos();
renderTodos();
}
// 할 일 완료/미완료 토글
function toggleTodo(id) {
const todo = todos.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed;
saveTodos();
renderTodos();
}
}
// 할 일 삭제
function deleteTodo(id) {
todos = todos.filter(t => t.id !== id);
saveTodos();
renderTodos();
}
// localStorage에 저장
function saveTodos() {
localStorage.setItem('todos', JSON.stringify(todos));
}
데이터 모델
Todo 항목의 데이터 구조입니다. localStorage에 JSON 배열로 저장됩니다:
// Todo 데이터 모델 (localStorage에 JSON으로 저장)
const todo = {
id: 1710000001, // Date.now() 기반 고유 ID
text: "기획서 작성", // 할 일 내용
completed: false, // 완료 여부
createdAt: "2026-03-20", // 생성 시간
priority: "high" // 'low' | 'medium' | 'high'
};
사용자 입력을 innerHTML로 직접 렌더링하면 XSS 공격에 취약합니다.
반드시 HTML 특수 문자를 이스케이프하거나 textContent를 사용하세요.
AI가 생성한 코드에 이 처리가 빠져있다면 추가를 요청하세요.
Step 4: 앱 실행 및 테스트
생성된 앱을 브라우저에서 실행해봅니다. 정적 파일이므로 직접 열거나 간단한 HTTP 서버를 사용합니다.
# 방법 1: 직접 열기
open index.html # Mac (Windows: start, Linux: xdg-open)
# 방법 2: HTTP 서버 실행 (권장)
python3 -m http.server 8080
# http://localhost:8080 으로 접속
file:// 프로토콜로 열면 localStorage가 제한될 수 있습니다.
로컬 HTTP 서버를 사용하면 실제 배포 환경과 동일한 조건에서 테스트할 수 있습니다.
기본 테스트 체크리스트
- 할 일을 입력하고 추가 버튼 클릭 (또는 Enter 키)
- 빈 입력으로 추가 시도 (유효성 검사 확인)
- 체크박스를 클릭하여 완료 표시 (취소선 확인)
- 삭제 버튼으로 항목 제거
- 페이지를 새로고침하여 데이터가 유지되는지 확인
- 필터 버튼 (전체/진행중/완료) 동작 확인
엣지 케이스 테스트
기본 기능이 작동하면, 아래 엣지 케이스도 확인하세요:
- 매우 긴 텍스트 입력 시 레이아웃 깨짐 여부
- 특수 문자(
< > &) 입력 시 XSS 방지 확인 - 모바일 화면에서의 터치 인터랙션
- 시크릿(Private) 모드에서 localStorage 동작
자동화된 테스트도 AI에게 요청할 수 있습니다:
"이 Todo 앱의 addTodo, toggleTodo, deleteTodo, saveTodos에 대한 단위 테스트를 순수 JavaScript로 작성해줘"
AI가 생성해주는 테스트 코드는 간단한 assert() 함수를 만들어
addTodo(), toggleTodo(), deleteTodo() 각각의
기대 결과를 검증합니다. 브라우저 콘솔에서 바로 실행할 수 있습니다.
Step 5: 기능 확장해보기
기본 기능이 작동하면, 추가 기능을 하나씩 요청해봅니다. Vibe Coding의 핵심은 점진적 확장입니다. 한 번에 모든 기능을 요청하지 말고, 기능 하나를 추가하고 테스트한 후 다음 기능을 요청하세요.
기능 1: 편집 기능
편집 버튼을 추가해줘. 편집 버튼을 누르면
텍스트가 입력창으로 바뀌고 수정 후 저장할 수 있게 해줘.
Enter 키를 누르거나 입력창 바깥을 클릭하면 저장돼야 해.
Escape 키를 누르면 편집이 취소돼야 해.
기능 2: 필터 기능
전체/진행중/완료된 할 일을 필터링하는
버튼 3개를 추가해줘. 현재 선택된 필터는
시각적으로 강조(active 클래스)되어야 해.
필터 상태도 localStorage에 저장해서 새로고침 후에도 유지해줘.
기능 3: 다크 모드
AI에게 "다크 모드 토글 버튼을 추가해줘. prefers-color-scheme을 기본값으로 사용하고 선택을 localStorage에 저장해줘"라고 요청합니다.
추가 아이디어
- 우선순위 표시: 드롭다운으로 높음/중간/낮음 설정, 색상 바로 시각화
- 드래그 앤 드롭 정렬: HTML5 Drag and Drop API로 순서 변경
각 기능을 추가한 후에는 반드시 Git 커밋을 하세요. 문제가 생기면 이전 커밋으로 쉽게 돌아갈 수 있습니다.
최종 결과물
완성된 Todo 앱의 구조는 다음과 같습니다:
Todo 앱 아키텍처
완성된 앱 기능 목록
| 카테고리 | 기능 | 구현 방식 |
|---|---|---|
| CRUD | 추가/수정/삭제 | form submit, 인라인 편집, 삭제 버튼 |
| 상태 관리 | 완료 토글, 필터링 | 체크박스 이벤트, 전체/진행중/완료 필터 |
| 데이터 | 영속 저장 | localStorage + JSON 직렬화 |
| UI/UX | 다크모드, 반응형, 애니메이션 | CSS Variables, 미디어 쿼리, transition |
| 접근성 | 키보드, 스크린 리더 | Enter/Escape 키, aria-label/role |
접근성 개선
완성도 높은 앱을 만들려면 접근성(Accessibility)도 고려해야 합니다. AI에게 접근성 개선을 요청하는 방법을 알아봅니다.
AI에게 "이 Todo 앱의 접근성을 개선해줘. aria-label, role, aria-live, Tab 키 내비게이션, focus 스타일을 추가해줘"라고 요청하세요.
핵심 접근성 요소:
- 체크박스에
aria-label="할 일 완료 표시"추가 - 버튼에
aria-label과title속성 추가 - 상태 변경 시
aria-live="polite"영역으로 스크린 리더에 알림 - 할 일 목록에
role="list"적용
Chrome DevTools의 Lighthouse 탭에서 접근성 점수를 확인할 수 있습니다.
AI에게 "Lighthouse 접근성 점수를 100점으로 만들어줘"라고 요청하면
구체적인 개선 사항을 알려줍니다.
배포 가이드
완성된 앱을 실제로 배포하여 다른 사람들과 공유해봅니다. 정적 사이트이므로 무료 호스팅 서비스를 활용할 수 있습니다.
GitHub Pages로 배포
가장 간단한 배포 방법입니다. GitHub 저장소에 코드를 올리고 Settings에서 Pages를 활성화합니다.
git remote add origin https://github.com/사용자명/todo-app.git
git add . && git commit -m "Todo 앱 완성"
git push -u origin main
# Settings → Pages → Branch: main → Save
# → https://사용자명.github.io/todo-app/
다른 배포 옵션
Netlify: netlify deploy --prod --dir . 또는
app.netlify.com/drop에서
폴더를 드래그 앤 드롭.
Vercel: npx vercel --prod 한 줄로 배포.
모두 무료 플랜을 제공합니다.
- 파일 경로가 모두 상대 경로인지 확인
- 콘솔에 에러가 없는지 확인
- 모바일 레이아웃 및 다크 모드 정상 동작 확인
- meta 태그(title, description, og:image) 설정 확인
localStorage는 브라우저 단위 저장이므로 다른 기기와 동기화되지 않습니다. 동기화가 필요하면 REST API 구축 튜토리얼을 참고하세요.
자주 발생하는 문제 해결
Vibe Coding으로 Todo 앱을 만들 때 자주 발생하는 문제와 해결 방법입니다.
문제 1: localStorage가 동작하지 않음
시크릿 모드나 iframe 환경에서 SecurityError가 발생할 수 있습니다.
try-catch로 감싸고, 사용 불가 시 메모리 기반 fallback을 사용하세요.
AI에게 에러 메시지를 그대로 전달하면 해결책을 제시합니다.
문제 2: 새로고침 시 데이터 손실
saveTodos()가 매번 호출되지 않는 경우가 있습니다.
데이터 변경이 일어나는 모든 함수에서 saveTodos()를 호출하는지 확인하세요.
또는 AI에게 Proxy 객체를 사용한 자동 저장 방식을 요청할 수 있습니다.
문제 3: 모바일에서 레이아웃 깨짐
모바일에서 입력창과 버튼이 겹치는 경우, AI에게 반응형 개선을 요청하세요. 입력창과 버튼을 세로 배치하고, 터치 영역을 최소 44px로 설정하면 해결됩니다.
문제가 발생하면 에러 메시지 전체를 복사하여 AI에게 전달하세요. "안 돼요"보다 구체적인 에러 메시지를 포함하면 훨씬 정확한 해결책을 얻을 수 있습니다. 브라우저 개발자 도구(F12)의 Console 탭에서 에러를 확인하세요.
고급 기능 도전
기본 기능을 모두 구현했다면, 더 고급 기능에 도전해볼 수 있습니다. 아래 기능들은 실무에서 자주 사용되는 패턴입니다.
- 카테고리/태그 시스템: 할 일에 카테고리(업무/개인/쇼핑)를 지정하고 색상 태그로 구분
- 마감일 및 알림: date input으로 마감일 설정, 지난 항목은 빨간색 강조
- 데이터 내보내기/가져오기: JSON 파일로 백업 및 복원
내보내기/가져오기 구현 힌트
Blob과 URL.createObjectURL()로 JSON 파일 다운로드(내보내기),
FileReader로 JSON 파일 읽기(가져오기)를 구현합니다.
AI에게 "할 일 목록을 JSON 파일로 내보내기/가져오기 기능을 추가해줘"라고 요청하세요.
다음 단계
이제 기본적인 웹 앱을 만들어보는 방법을 배웠습니다. 다음 프로젝트도 도전해 보세요!
핵심 정리
- 폴더 생성: 프로젝트 폴더를 만들고 Git 초기화, AI 코딩 도구 실행
- 요구사항 명시: 기술 스택, 기능 목록, UI 요구사항을 구체적으로 나열
- 코드 생성: AI가 HTML/CSS/JS 파일을 자동으로 생성
- 코드 이해: 생성된 코드의 구조와 데이터 흐름 파악
- 테스트: 기본 기능과 엣지 케이스를 모두 확인
- 점진적 확장: 편집, 필터, 다크모드 등 기능을 하나씩 추가
- 보안: XSS 방지, 입력 유효성 검사 적용
- 접근성: aria 속성, 키보드 내비게이션 지원
- 배포: GitHub Pages, Netlify, Vercel 등으로 무료 배포
요구사항 정의 → AI에게 요청 → 코드 확인 → 테스트 → 피드백 → 반복. 이 순환을 빠르게 돌릴수록 더 좋은 결과물을 만들 수 있습니다.