실전 예제: 할 일 관리 앱 만들기
작은 앱 하나를 끝까지 만드는 이유
이제부터는 진짜 앱을 만들어 보겠습니다. 첫 실전 예제는 할 일 관리 앱, 흔히 말하는 Todo 앱입니다. 너무 단순해 보이나요? 오히려 그래서 좋습니다. Todo 앱에는 앱 개발의 기본기가 거의 다 들어 있습니다. 사용자가 입력하고, 목록이 화면에 나타나고, 버튼을 눌러 상태가 바뀌고, 삭제되고, 새로고침해도 데이터가 남아야 합니다.
초보자가 처음부터 로그인, 데이터베이스, 결제, 배포까지 들어간 앱을 만들면 Codex가 만든 결과가 맞는지 판단하기 어렵습니다. 반면 Todo 앱은 결과가 눈에 보입니다. "추가 버튼을 눌렀는데 목록에 안 들어간다", "완료 필터를 눌렀는데 완료된 할 일만 보이지 않는다", "새로고침했더니 사라졌다"처럼 문제를 직접 확인할 수 있습니다. 이 직접 확인이 중요합니다. Codex와 앱을 만들 때 실력은 코드를 얼마나 많이 외우느냐보다, 요구사항을 작게 나누고 결과를 검토하고 다시 지시하는 루프에서 자랍니다.
Codex는 코드를 대신 써주는 채팅창이라기보다, 프로젝트 안에서 파일을 읽고 고치고 명령을 실행하고 변경 사항을 리뷰할 수 있는 코딩 에이전트에 가깝습니다. 특히 Codex App은 프로젝트별 스레드, 병렬 작업, Git 기능, worktree 지원을 한 화면에서 다룰 수 있는 데스크톱 작업 공간으로 설계되어 있습니다.1 이번 장에서는 이 장점을 너무 복잡하게 쓰지 않고, 초보자에게 가장 안전한 방식으로 하나의 작은 앱을 끝까지 완성해 보겠습니다.
이번 실습의 목표는 "멋진 Todo 앱"이 아닙니다. 목표는 다음 개발 루프를 몸에 익히는 것입니다.
요구사항을 적고, Codex에게 계획을 먼저 받습니다. 계획을 확인한 다음 작은 단위로 구현을 맡깁니다. 브라우저에서 직접 눌러 보며 문제를 찾습니다. 증상을 구체적으로 말해 수정하게 합니다. 마지막으로 변경 사항을 검토하고 커밋합니다.
이 루프 하나만 익혀도 이후 날씨 대시보드, 로그인 앱, 미니 SaaS를 만들 때 훨씬 덜 흔들립니다.

오늘 만들 앱의 완성 모습
우리가 만들 앱은 브라우저에서 실행되는 간단한 Todo 앱입니다. 기술 스택은 초보자가 따라가기 쉬운 Vite + React + JavaScript로 잡겠습니다. Vite는 프런트엔드 개발 서버와 빌드 도구입니다. 쉽게 말해 React 앱을 빠르게 실행하고 개발 중 변경 사항을 바로 확인하게 해 주는 도구입니다.
완성된 앱은 다음 기능을 가져야 합니다.
할 일을 입력하고 추가할 수 있다.
각 할 일을 완료 또는 진행 중 상태로 바꿀 수 있다.
필요 없는 할 일을 삭제할 수 있다.
전체, 진행 중, 완료 필터로 목록을 나누어 볼 수 있다.
브라우저를 새로고침해도 할 일이 유지된다.
빈 입력이나 공백만 있는 입력은 추가되지 않는다.
너무 긴 할 일을 입력해도 화면이 깨지지 않는다.
README에 설치, 실행, 사용 방법이 정리되어 있다.
여기서 데이터베이스는 쓰지 않습니다. 대신 브라우저의 localStorage를 사용합니다. localStorage는 사용자의 브라우저 안에 작은 데이터를 저장하는 기능입니다. 서버가 없어도 새로고침 후 데이터를 유지할 수 있어서 Todo 앱 첫 실습에 잘 맞습니다. 단, 브라우저별·기기별 저장소이므로 실제 서비스의 사용자 계정 데이터 저장소로 쓰기에는 부족합니다. 지금은 "프런트엔드 상태와 저장 흐름을 익히는 연습용 저장소"라고 이해하면 충분합니다.
먼저 요구사항을 사람이 쓴다
Codex에게 바로 "Todo 앱 만들어줘"라고 말하고 싶은 마음이 들 수 있습니다. 물론 그렇게 해도 무언가 만들어질 가능성은 높습니다. 하지만 초보자일수록 바로 코딩보다 요구사항 정리가 먼저입니다. 요구사항이 흐릿하면 결과도 흐릿합니다.
프로젝트 폴더를 만들기 전에, 아래 내용을 메모장이나 프로젝트의 docs/requirements.md에 적어 둡니다. 아직 파일을 만들지 않아도 괜찮습니다. 중요한 것은 Codex에게 전달할 기준을 사람이 먼저 갖는 것입니다.
# Todo 앱 최소 요구사항
## 목표
브라우저에서 실행되는 간단한 Todo 앱을 만든다.
초보자가 코드를 읽고 수정할 수 있도록 구조를 단순하게 유지한다.
## 기술 스택
- Vite
- React
- JavaScript
- CSS
- localStorage
## 필수 기능
1. 사용자는 입력창에 할 일을 쓰고 추가 버튼 또는 Enter 키로 추가할 수 있다.
2. 빈 문자열 또는 공백만 있는 문자열은 추가되지 않는다.
3. 추가된 할 일은 목록에 표시된다.
4. 각 할 일은 완료 체크를 토글할 수 있다.
5. 각 할 일은 삭제할 수 있다.
6. 전체, 진행 중, 완료 필터를 제공한다.
7. 할 일 목록은 localStorage에 저장된다.
8. 새로고침 후에도 저장된 할 일이 다시 보인다.
9. 긴 텍스트가 들어와도 카드 밖으로 튀어나가지 않는다.
## 완료 조건
- npm install 후 npm run dev로 실행된다.
- 브라우저에서 추가, 완료, 삭제, 필터가 동작한다.
- 새로고침 후 데이터가 유지된다.
- 기본 테스트 시나리오를 README에 적는다.
- Git diff를 검토한 뒤 의미 있는 커밋 메시지로 커밋한다.이 정도면 충분합니다. "예쁜 애니메이션", "드래그 앤 드롭", "로그인", "클라우드 동기화"는 일부러 제외했습니다. 첫 앱의 핵심은 작게 완성하는 것입니다. Codex 활용에서도 작은 작업에서 시작해 분석, 수정, 검증으로 확장하는 방식이 안정적입니다.2
새 프로젝트 또는 새 스레드에서 시작하기
이제 작업 공간을 준비합니다. 이미 이전 장에서 만든 연습용 폴더가 있다면 그 안에서 새 폴더를 만들어도 됩니다. 중요한 것은 기존 중요한 프로젝트와 섞지 않는 것입니다.
터미널을 사용할 경우 다음처럼 시작할 수 있습니다.
mkdir codex-todo-practice
cd codex-todo-practice
git initCodex App을 사용한다면 이 폴더를 프로젝트로 추가합니다. Codex App에서는 프로젝트가 보통 로컬 폴더와 연결되고, 에이전트는 해당 프로젝트 맥락 안에서 파일을 읽고 수정합니다. 앱 안에서는 스레드별로 작업을 나눌 수 있고, 변경 사항 diff에 코멘트를 남기거나 에디터에서 파일을 열어 직접 고칠 수도 있습니다.3
이번 장에서는 스레드를 하나만 써도 됩니다. 다만 습관은 중요합니다. 새 기능, 버그 수정, 문서 정리를 한 스레드에 끝없이 섞으면 나중에 대화 맥락이 지저분해집니다. 이번에는 작은 실습이므로 하나의 스레드로 진행하되, 다음과 같은 이름을 붙였다고 생각해 봅시다.
Todo 앱 첫 구현스레드 첫 메시지는 코딩 요청이 아니라 계획 요청이어야 합니다.
이 폴더에서 초보자용 Todo 앱을 만들고 싶습니다.
요구사항:
- Vite + React + JavaScript 사용
- 할 일 추가, 완료 토글, 삭제
- 전체/진행 중/완료 필터
- localStorage 저장과 새로고침 후 복원
- 빈 입력과 공백 입력 방지
- 긴 텍스트가 UI를 깨뜨리지 않도록 처리
바로 파일을 만들지 말고 먼저 다음을 제안해 주세요.
1. 추천 파일 구조
2. 구현 순서
3. 실행 명령어
4. 각 단계의 확인 방법
5. 초보자가 주의해야 할 부분
제가 승인한 뒤에 단계별로 파일을 생성하거나 수정해 주세요.이 프롬프트에는 좋은 점이 많습니다. 목표가 있고, 기술 스택이 있고, 필수 기능이 있고, "바로 파일을 만들지 말라"는 제약이 있습니다. 또 Codex가 무엇을 먼저 답해야 하는지도 분명합니다. Codex에게 구현보다 계획을 먼저 요청하면 불필요한 왕복이 줄어듭니다. 특히 Codex App의 계획 모드나 실행 전 계획 확인 흐름은 큰 변경 전에 방향을 맞추는 데 유용합니다.4
Codex가 제안한 계획을 검토하기
Codex는 아마 다음과 비슷한 구조를 제안할 것입니다.
codex-todo-practice/
package.json
index.html
src/
main.jsx
App.jsx
App.css
README.md
AGENTS.md또는 컴포넌트를 조금 더 나누어 다음처럼 제안할 수도 있습니다.
src/
components/
TodoInput.jsx
TodoFilters.jsx
TodoList.jsx
TodoItem.jsx
App.jsx
App.css
main.jsx둘 다 괜찮습니다. 다만 초보자에게는 너무 많은 파일이 오히려 부담이 될 수 있습니다. 이번 장에서는 아래 정도가 적당합니다.
src/
components/
TodoInput.jsx
TodoFilters.jsx
TodoList.jsx
App.jsx
App.css
main.jsxTodoItem.jsx까지 분리해도 되지만, 처음에는 TodoList.jsx 안에서 각 항목을 렌더링해도 충분합니다. 중요한 것은 파일을 나누는 이유를 이해하는 것입니다. 입력 영역은 TodoInput, 필터 버튼은 TodoFilters, 목록은 TodoList가 맡습니다. 이렇게 나누면 나중에 Codex에게 "필터 버튼 동작만 고쳐줘"라고 좁게 지시하기 쉬워집니다.
Codex의 계획이 너무 복잡하다면 즉시 줄여야 합니다.
계획이 초보자에게 조금 복잡합니다.
이번 실습에서는 테스트 라이브러리와 라우팅은 제외하고,
Vite + React + JavaScript + CSS + localStorage만 사용해 주세요.
파일은 최대한 적게 유지하고, 컴포넌트는 TodoInput, TodoFilters, TodoList 정도로만 나누어 주세요.
수정된 파일 구조와 구현 순서를 다시 제안해 주세요.Codex의 제안을 그대로 따라갈 필요는 없습니다. 우리가 운전하고 Codex는 빠르게 도와주는 동료입니다. 이 감각을 잃지 않아야 합니다.
프로젝트 뼈대 만들기
계획이 마음에 들면 첫 번째 구현 요청을 보냅니다. 여전히 범위는 작게 잡습니다.
좋습니다. 이제 프로젝트 뼈대만 만들어 주세요.
범위:
- Vite + React + JavaScript 프로젝트 생성에 필요한 파일 작성
- package.json, index.html, src/main.jsx, src/App.jsx, src/App.css 생성
- 아직 Todo 기능은 최소 표시만 하고, 화면에는 앱 제목과 간단한 안내 문구만 보여 주세요.
제약:
- 외부 UI 라이브러리는 설치하지 마세요.
- TypeScript는 사용하지 마세요.
- 실행 명령어를 마지막에 알려 주세요.
완료 기준:
- npm install
- npm run dev
- 브라우저에서 제목이 보임Codex가 파일을 만들면 바로 실행합니다.
npm install
npm run dev터미널에 보통 http://localhost:5173 같은 주소가 나옵니다. 브라우저로 열어 봅니다. Codex App을 사용한다면 오른쪽 패널이나 Run 설정에 실행 명령을 지정해 앱을 미리볼 수 있습니다. 최신 Codex App은 개발 서버 실행, 터미널, 브라우저 미리보기 같은 작업을 한 흐름 안에서 다루도록 발전하고 있습니다.5
화면에 제목이 보이면 첫 번째 성공입니다. 이 단계에서 기능이 없다고 실망할 필요가 없습니다. 오히려 좋습니다. 앱 개발은 작은 성공 지점을 쌓는 게임입니다.
Git 상태도 확인합니다.
git status아직 커밋하지 않아도 됩니다. 하지만 어떤 파일이 생겼는지는 반드시 봅니다.
git diff --statCodex App을 사용한다면 diff 패널에서 파일별 변경 사항을 확인합니다. 변경 사항을 좋아하면 커밋하고, 마음에 들지 않으면 되돌리는 것이 기본입니다. OpenAI의 Codex workflow 문서에서도 원하는 변경은 커밋하고 원하지 않는 변경은 되돌리며, 사용자가 수정하거나 되돌린 내용을 Codex에게 알려 다음 작업에서 덮어쓰지 않게 하라고 권장합니다.6
할 일 입력 컴포넌트 구현하기
이제 첫 기능을 추가합니다. 한 번에 전체 Todo 앱을 만들라고 하지 않습니다. 입력과 추가만 맡깁니다.
이제 Todo 입력 기능을 구현해 주세요.
대상 파일:
- src/App.jsx
- src/components/TodoInput.jsx가 필요하면 생성
- src/App.css
목표:
- 입력창에 할 일을 쓰고 추가 버튼을 누르면 목록에 추가되게 해 주세요.
- Enter 키를 눌러도 추가되게 해 주세요.
- 빈 문자열 또는 공백만 있는 입력은 추가하지 마세요.
제약:
- 아직 localStorage 저장은 하지 마세요.
- 아직 완료 토글, 삭제, 필터는 구현하지 마세요.
- React useState만 사용해 단순하게 구현해 주세요.
완료 기준:
- 입력 후 버튼 클릭으로 목록에 표시됨
- 입력 후 Enter로 목록에 표시됨
- 공백만 입력하면 추가되지 않음
- 추가 후 입력창이 비워짐이 프롬프트는 대상 파일, 목표, 제약, 완료 기준이 분명합니다. 앞 장에서 배운 좋은 프롬프트의 네 요소가 그대로 들어 있습니다. Codex는 이런 요청에 훨씬 안정적으로 반응합니다.
구현이 끝나면 브라우저에서 직접 확인합니다.
테스트 1: "우유 사기" 입력 후 추가 버튼 클릭
테스트 2: "운동하기" 입력 후 Enter
테스트 3: 스페이스만 여러 번 입력 후 추가 버튼 클릭
테스트 4: 추가 후 입력창이 비워지는지 확인문제가 없으면 다음으로 갑니다. 문제가 있으면 증상을 구체적으로 말합니다.
나쁜 수정 요청은 이렇습니다.
안 돼요. 고쳐 주세요.좋은 수정 요청은 이렇습니다.
입력창에 "우유 사기"를 쓰고 Enter를 누르면 목록에는 추가되지만 입력창이 비워지지 않습니다.
추가 버튼을 눌렀을 때는 입력창이 정상적으로 비워집니다.
Enter 처리 로직과 버튼 클릭 로직이 같은 addTodo 함수를 사용하도록 수정해 주세요.
수정 후 어떤 파일의 어떤 부분을 바꿨는지 설명해 주세요.Codex는 구체적인 증상과 재현 방법을 받을수록 원인을 찾기 쉽습니다. 특히 UI 문제는 "어디서, 무엇을 눌렀고, 기대 결과와 실제 결과가 어떻게 다른지"를 말해 주는 것이 좋습니다.
완료 체크와 삭제 기능 추가하기
입력 기능이 동작하면 이제 Todo 항목에 상태를 부여합니다. 할 일 하나를 단순 문자열로 저장했다면 이제 객체로 바꾸어야 합니다.
예를 들면 이런 구조입니다.
{
id: 1710000000000,
text: '우유 사기',
completed: false
}초보자에게 객체는 "관련 정보를 묶은 상자"라고 생각하면 됩니다. text는 할 일 내용, completed는 완료 여부입니다. id는 각 항목을 구별하는 이름표입니다.
Codex에게 다음처럼 요청합니다.
이제 Todo 항목을 문자열이 아니라 객체로 관리하도록 바꾸고,
완료 체크와 삭제 기능을 추가해 주세요.
대상 파일:
- src/App.jsx
- src/components/TodoList.jsx가 필요하면 생성
- src/App.css
목표:
- 각 Todo는 id, text, completed 속성을 가진 객체가 되게 해 주세요.
- 체크박스 또는 버튼으로 completed 값을 토글할 수 있게 해 주세요.
- 삭제 버튼으로 해당 Todo를 제거할 수 있게 해 주세요.
- 완료된 Todo는 텍스트에 취소선 또는 흐린 스타일을 적용해 주세요.
제약:
- 아직 필터와 localStorage는 구현하지 마세요.
- id는 초보자가 이해하기 쉬운 방식으로 생성해 주세요. Date.now()를 사용해도 됩니다.
- 기존 입력 기능은 유지해 주세요.
완료 기준:
- 새 Todo 추가 가능
- 완료 상태 토글 가능
- 삭제 가능
- 완료된 항목이 시각적으로 구분됨완료 후 확인합니다. 여기서 초보자가 자주 만나는 버그가 있습니다. 체크를 누르면 엉뚱한 항목이 완료되거나, 삭제를 누르면 모든 항목이 사라지거나, 완료 스타일은 바뀌는데 데이터는 바뀌지 않는 경우입니다.
그럴 때는 이렇게 말합니다.
버그가 있습니다.
재현 방법:
1. "A", "B", "C"를 순서대로 추가합니다.
2. B의 완료 체크를 누릅니다.
기대 결과:
- B만 완료 상태가 됩니다.
실제 결과:
- A가 완료 상태로 바뀝니다.
각 Todo의 id를 기준으로 토글하도록 로직을 점검하고 수정해 주세요.
수정 후 왜 문제가 생겼는지 초보자도 이해할 수 있게 설명해 주세요.이런 식으로 재현 단계가 있으면 Codex가 훨씬 정확하게 고칩니다. "B를 눌렀는데 A가 바뀐다"는 말은 사람 개발자에게도 좋은 버그 리포트입니다.
필터 버튼 동작 추가하기
다음은 전체, 진행 중, 완료 필터입니다. 이 기능은 앱 상태의 두 번째 축을 만듭니다. 첫 번째 상태는 todos, 즉 할 일 목록입니다. 두 번째 상태는 filter, 즉 지금 어떤 목록을 보고 있는지입니다.
Codex에게 요청합니다.
Todo 필터 기능을 추가해 주세요.
대상 파일:
- src/App.jsx
- src/components/TodoFilters.jsx가 필요하면 생성
- src/App.css
목표:
- 전체, 진행 중, 완료 버튼을 보여 주세요.
- 전체는 모든 Todo를 보여 줍니다.
- 진행 중은 completed가 false인 Todo만 보여 줍니다.
- 완료는 completed가 true인 Todo만 보여 줍니다.
- 현재 선택된 필터 버튼은 시각적으로 구분해 주세요.
제약:
- URL 라우팅은 사용하지 마세요.
- localStorage는 아직 구현하지 마세요.
- 기존 추가, 완료 토글, 삭제 기능을 깨뜨리지 마세요.
완료 기준:
- 필터 버튼을 누르면 목록이 즉시 바뀜
- 완료 토글 후 필터 결과가 자연스럽게 반영됨
- 선택된 필터가 눈에 보임필터 기능을 확인할 때는 데이터를 조금 섞어야 합니다.
1. "밥 먹기", "책 읽기", "메일 답장"을 추가한다.
2. "책 읽기"만 완료 처리한다.
3. 전체 필터에서 3개가 보이는지 확인한다.
4. 진행 중 필터에서 2개가 보이는지 확인한다.
5. 완료 필터에서 1개가 보이는지 확인한다.
6. 완료 필터 상태에서 완료 항목을 삭제했을 때 목록이 자연스럽게 비는지 확인한다.필터 기능은 겉보기보다 실수가 많습니다. 예를 들어 "진행 중" 필터를 누른 상태에서 새 할 일을 추가했는데 보이지 않는다면, 새 할 일의 completed 기본값이 잘못되었을 수 있습니다. 이때도 증상을 그대로 말하면 됩니다.
진행 중 필터를 선택한 상태에서 새 Todo를 추가하면 목록에 바로 나타나야 하는데 보이지 않습니다.
새 Todo의 completed 기본값과 필터링 로직을 확인해 주세요.
기존 기능을 유지하면서 최소 수정으로 고쳐 주세요.localStorage로 새로고침 후 데이터 유지하기
이제 가장 앱다운 기능을 붙입니다. 새로고침해도 데이터가 유지되게 하겠습니다. 이 단계에서 초보자가 이해해야 할 개념은 두 가지입니다.
첫째, React의 useState에 들어 있는 데이터는 화면이 열려 있는 동안만 살아 있습니다. 새로고침하면 처음부터 다시 시작합니다. 둘째, localStorage에 저장하면 브라우저 안에 문자열 형태로 데이터가 남습니다. 객체나 배열은 그대로 저장할 수 없기 때문에 JSON.stringify로 문자열로 바꾸고, 다시 꺼낼 때 JSON.parse로 배열로 되돌립니다.
Codex에게 다음처럼 요청합니다.
Todo 목록을 localStorage에 저장하고 복원하는 기능을 추가해 주세요.
대상 파일:
- src/App.jsx
목표:
- 앱이 처음 로드될 때 localStorage에서 저장된 todos를 읽어 초기 상태로 사용합니다.
- todos가 변경될 때마다 localStorage에 저장합니다.
- 저장 키는 "codex-todo-items"를 사용해 주세요.
제약:
- localStorage에는 todos 배열만 저장해 주세요. filter 상태는 저장하지 않아도 됩니다.
- JSON.parse 실패 가능성을 고려해 앱이 깨지지 않도록 방어 코드를 넣어 주세요.
- 기존 추가, 완료 토글, 삭제, 필터 기능을 유지해 주세요.
완료 기준:
- Todo를 몇 개 추가한 뒤 새로고침해도 남아 있음
- 완료 상태도 새로고침 후 유지됨
- 삭제한 Todo는 새로고침 후 다시 나타나지 않음
- localStorage 데이터가 손상되어도 앱이 빈 목록으로 시작함여기서 "JSON.parse 실패 가능성"이라는 말이 낯설 수 있습니다. 브라우저 개발자 도구에서 localStorage 값을 사용자가 직접 이상하게 바꾸거나, 예전 버전 앱이 다른 형태로 데이터를 저장한 경우 JSON.parse가 에러를 낼 수 있습니다. 작은 Todo 앱이라도 이런 방어 코드를 넣어 보는 습관은 좋습니다.
확인 방법은 간단합니다.
1. "청소하기"를 추가한다.
2. 완료 체크를 누른다.
3. 브라우저를 새로고침한다.
4. "청소하기"가 남아 있고 완료 상태도 유지되는지 본다.
5. 삭제한다.
6. 다시 새로고침한다.
7. 삭제한 항목이 다시 나타나지 않는지 본다.만약 새로고침 후 데이터가 사라진다면 이렇게 요청합니다.
localStorage 저장이 동작하지 않는 것 같습니다.
재현 방법:
1. Todo를 2개 추가합니다.
2. 브라우저를 새로고침합니다.
기대 결과:
- 추가한 Todo 2개가 다시 보여야 합니다.
실제 결과:
- 목록이 비어 있습니다.
확인 요청:
- 앱 최초 로드 시 localStorage를 읽는 코드가 실제 초기 상태에 연결되어 있는지 확인해 주세요.
- todos 변경 시 저장하는 useEffect 의존성 배열이 올바른지 확인해 주세요.
- 수정 후 초보자도 이해할 수 있게 저장과 복원 흐름을 설명해 주세요.이 프롬프트는 단순히 "고쳐줘"가 아니라 의심 지점까지 알려 줍니다. 초보자라도 Codex가 쓴 설명을 읽으며 개념을 익힐 수 있습니다.
긴 텍스트와 빈 상태 UI 다듬기
앱이 기능적으로 동작하면 이제 사용자가 이상한 입력을 했을 때를 봐야 합니다. 사람은 항상 예상대로 쓰지 않습니다. "aaaaaaaa..."처럼 아주 긴 글을 넣을 수도 있고, 필터 결과가 비어 있을 수도 있습니다.
Codex에게 UI 방어를 요청합니다.
Todo 앱의 기본 UI 방어와 빈 상태를 개선해 주세요.
대상 파일:
- src/App.jsx
- src/components/TodoList.jsx
- src/App.css
목표:
- Todo가 하나도 없을 때 안내 문구를 보여 주세요.
- 현재 필터 결과가 비어 있을 때도 자연스러운 안내 문구를 보여 주세요.
- 매우 긴 Todo 텍스트가 들어와도 카드나 화면 밖으로 튀어나가지 않게 CSS를 수정해 주세요.
- 전체적인 간격과 버튼 스타일을 초보자용 예제로 보기 좋게 정리해 주세요.
제약:
- 외부 CSS 프레임워크는 사용하지 마세요.
- 기능 로직은 필요 이상으로 바꾸지 마세요.
- 접근성을 위해 버튼 텍스트는 의미 있게 유지해 주세요.
완료 기준:
- 빈 목록에서 안내 문구가 보임
- 완료 필터에 결과가 없을 때 안내 문구가 보임
- 긴 텍스트가 줄바꿈되어 화면을 깨뜨리지 않음긴 텍스트 테스트는 직접 해 봅니다.
이것은아주아주아주아주아주아주아주아주아주아주긴할일입니다이텍스트가화면밖으로나가면안됩니다화면이 깨지면 스크린샷을 첨부하거나 구체적으로 설명합니다. Codex App은 이미지와 파일을 맥락으로 사용할 수 있고, 프런트엔드 작업에서는 스크린샷을 보며 특정 UI 문제를 고치는 흐름이 유용합니다.7
예를 들어 이렇게 말합니다.
스크린샷을 보면 긴 Todo 텍스트가 카드 오른쪽 밖으로 삐져나갑니다.
Todo 텍스트 영역에 줄바꿈이 적용되도록 CSS를 수정해 주세요.
가능하면 word-break 또는 overflow-wrap 중 이 상황에 적절한 속성을 사용하고,
왜 그 속성을 선택했는지 설명해 주세요.이제 Codex는 단순히 "예쁘게"가 아니라 명확한 화면 문제를 해결합니다.
Codex에게 테스트 시나리오를 만들게 하기
초보자는 "테스트"라고 하면 Jest, Vitest, Playwright 같은 도구부터 떠올릴 수 있습니다. 하지만 첫 앱에서는 자동화 테스트보다 수동 테스트 시나리오가 먼저입니다. 수동 테스트는 사람이 직접 눌러 보며 확인하는 절차입니다. 이 절차가 명확해야 나중에 자동화 테스트도 만들 수 있습니다.
Codex에게 테스트 시나리오를 요청합니다.
현재 Todo 앱을 기준으로 초보자가 브라우저에서 직접 확인할 수 있는 수동 테스트 시나리오를 만들어 주세요.
포함할 엣지 케이스:
- 빈 입력
- 공백만 입력
- 매우 긴 할 일
- 빠른 삭제
- 완료 체크를 여러 번 빠르게 전환
- 전체/진행 중/완료 필터 변경
- 새로고침 후 데이터 유지
- localStorage 데이터가 손상된 경우
출력 형식:
- 번호가 있는 체크리스트
- 각 항목에 재현 단계, 기대 결과 포함
- README에 넣기 좋은 문장으로 작성
아직 파일은 수정하지 말고, 먼저 시나리오만 제안해 주세요.Codex가 제안한 테스트 시나리오를 사람이 직접 수행합니다. 여기서 버그가 나오면 그 버그는 선물입니다. 작은 앱에서 버그를 잡는 연습을 하면 큰 앱에서 덜 당황합니다.
예를 들어 빠르게 완료 체크와 삭제를 반복하다가 에러가 났다고 해 봅시다.
빠르게 완료 체크를 여러 번 누른 뒤 바로 삭제하면 콘솔에 에러가 나타납니다.
재현 방법:
1. Todo를 3개 추가합니다.
2. 두 번째 Todo의 완료 체크를 빠르게 5번 누릅니다.
3. 곧바로 삭제 버튼을 누릅니다.
실제 결과:
- 화면은 동작하지만 브라우저 콘솔에 경고 또는 에러가 표시됩니다.
요청:
- 상태 업데이트 로직이 이전 상태를 안전하게 기반으로 하는지 확인해 주세요.
- 필요하면 setTodos(prevTodos => ...) 형태로 수정해 주세요.
- 수정 후 왜 이 방식이 안전한지 설명해 주세요.React에서 상태를 바꿀 때 이전 상태를 기준으로 계산해야 하는 경우가 많습니다. Codex에게 이 부분을 설명하게 하면 코드만 얻는 것이 아니라 개념까지 배울 수 있습니다.
방어 코드 추가 요청하기
테스트 시나리오를 수행한 뒤 다음과 같은 추가 방어 코드를 요청할 수 있습니다.
수동 테스트 결과를 바탕으로 방어 코드를 보강해 주세요.
보강할 내용:
- 입력값은 trim한 뒤 저장해 주세요.
- 너무 긴 입력은 120자로 제한해 주세요.
- 120자를 넘으면 추가하지 말고 간단한 안내 메시지를 보여 주세요.
- localStorage에서 읽은 데이터가 배열이 아니면 빈 배열로 처리해 주세요.
- 각 Todo 객체에 id, text, completed가 올바르게 있는지 최소한으로 검증해 주세요.
제약:
- 복잡한 상태 관리 라이브러리는 사용하지 마세요.
- 초보자가 읽기 어렵게 과도하게 추상화하지 마세요.
완료 기준:
- 공백 입력 방지
- 긴 입력 방지
- 손상된 localStorage 데이터 방어
- 기존 주요 기능 유지여기서 "120자 제한"은 필수 정답이 아닙니다. 우리가 정한 제품 정책입니다. 앱 개발은 늘 이런 선택의 연속입니다. Codex에게도 "알아서 좋은 대로"가 아니라 우리가 정한 기준을 줘야 합니다.
이제 브라우저에서 다시 확인합니다.
1. 공백만 입력 → 추가되지 않아야 함
2. 121자 이상 입력 → 안내 메시지 표시
3. 정상 입력 → 추가됨
4. 완료 토글 → 정상
5. 삭제 → 정상
6. 필터 → 정상
7. 새로고침 → 데이터 유지이 과정을 거치면 Todo 앱은 단순하지만 꽤 탄탄해집니다.
변경 사항 리뷰하기
기능이 완성되었다고 바로 커밋하면 안 됩니다. 먼저 변경 사항을 봅니다.
터미널에서는 다음 명령을 사용합니다.
git status
git diff파일이 많아 보기 어렵다면 통계부터 봅니다.
git diff --statCodex App에서는 diff 패널을 열어 변경된 파일을 확인합니다. 앱 안에서 변경 사항을 리뷰하고, diff에 코멘트를 남기거나 직접 에디터로 열어 수정할 수 있습니다.3
초보자는 diff를 볼 때 모든 코드를 완벽히 이해하려 하지 않아도 됩니다. 대신 다음 질문을 던집니다.
내가 요청하지 않은 파일이 바뀌었는가?
기능과 상관없는 큰 리팩터링이 들어갔는가?
API 키, 비밀번호, 개인 정보 같은 민감한 값이 들어갔는가?
실행 명령과 파일 구조가 README와 맞는가?
삭제되면 안 되는 파일이 삭제되었는가?
만약 Codex가 요청하지 않은 변경을 했다면 되돌리거나 수정 지시를 합니다.
diff를 확인해 보니 Todo 기능과 관련 없는 파일까지 수정되었습니다.
이번 커밋에는 Todo 앱 구현에 필요한 변경만 포함하고 싶습니다.
관련 없는 변경을 되돌릴 수 있도록 어떤 파일을 되돌려야 하는지 알려 주세요.
필요하면 해당 파일의 변경을 원래대로 되돌려 주세요.중요한 점이 있습니다. 사용자가 어떤 변경을 되돌리거나 직접 수정했다면 Codex에게 알려야 합니다. 그래야 다음 작업에서 Codex가 같은 변경을 다시 덮어쓰지 않습니다.6
README 작성하기
이제 프로젝트를 다른 사람이 열어도 실행할 수 있게 README를 씁니다. README는 장식이 아닙니다. 미래의 내가 프로젝트를 다시 열었을 때 가장 먼저 읽는 설명서입니다.
Codex에게 요청합니다.
README.md를 작성해 주세요.
포함할 내용:
- 프로젝트 이름: Codex Todo Practice
- 프로젝트 소개
- 주요 기능
- 기술 스택
- 설치 방법
- 실행 방법
- 사용 방법
- 수동 테스트 체크리스트
- 초보자가 배운 점
실제 명령어:
- npm install
- npm run dev
- npm run build가 가능하면 빌드 확인 명령도 포함
제약:
- 과장된 표현은 피하고, 현재 구현된 기능만 적어 주세요.
- 아직 배포하지 않았으므로 배포 URL은 적지 마세요.
- 한국어로 작성해 주세요.README가 생성되면 반드시 읽어 봅니다. 종종 Codex가 실제로 없는 명령어를 적을 수 있습니다. 예를 들어 npm test 스크립트가 없는데 README에 npm test를 쓰는 경우가 있습니다. 이럴 때는 수정해야 합니다.
README에 npm test 명령이 적혀 있지만 package.json에는 test 스크립트가 없습니다.
이번 프로젝트에서는 자동화 테스트를 아직 추가하지 않았으므로,
npm test 문구를 제거하고 수동 테스트 체크리스트 중심으로 README를 수정해 주세요.문서는 코드와 같아서 실제와 맞아야 합니다.
빌드 확인과 마지막 점검
개발 서버에서 잘 보이는 것과 배포용 빌드가 되는 것은 다릅니다. Vite 프로젝트라면 보통 다음 명령으로 빌드를 확인합니다.
npm run build문제가 없다면 dist 폴더가 생깁니다. dist는 빌드 결과물이므로 보통 Git에 커밋하지 않습니다. .gitignore에 dist/가 들어 있는지 확인합니다.
Codex에게 마지막 점검을 부탁할 수 있습니다.
커밋 전에 마지막 점검을 해 주세요.
확인할 것:
- package.json의 scripts가 README와 일치하는지
- .gitignore에 node_modules와 dist가 포함되어 있는지
- Todo 주요 기능에 불필요한 복잡성이 없는지
- 초보자가 읽기 어려운 과도한 추상화가 없는지
- localStorage 저장/복원 로직에 명백한 오류가 없는지
파일을 수정하기 전에 먼저 점검 결과를 목록으로 알려 주세요.
수정이 꼭 필요한 항목만 제안해 주세요.여기서도 "먼저 점검 결과"를 요청했습니다. Codex가 바로 바꾸기 전에 사람이 판단할 시간을 얻는 것입니다.
필요한 수정이 있다면 하나씩 승인합니다.
제안한 항목 중 .gitignore 보완과 README 명령어 수정만 진행해 주세요.
기능 코드 리팩터링은 이번 커밋에서는 하지 않겠습니다.이렇게 범위를 줄이면 마지막 순간에 앱이 괜히 흔들리는 일을 줄일 수 있습니다.
Git 상태 확인과 커밋하기
이제 커밋합니다. 먼저 상태를 확인합니다.
git status예상되는 변경 파일은 대략 다음과 같습니다.
AGENTS.md
README.md
index.html
package.json
src/main.jsx
src/App.jsx
src/App.css
src/components/TodoInput.jsx
src/components/TodoFilters.jsx
src/components/TodoList.jsx프로젝트 생성 방식에 따라 package-lock.json도 있을 수 있습니다. package-lock.json은 npm이 설치한 패키지 버전을 기록하는 파일이므로 보통 함께 커밋합니다.
원하지 않는 파일이 없는지 확인한 뒤 추가합니다.
git add .
git status그리고 커밋합니다.
git commit -m "feat: build basic todo app"커밋 메시지는 너무 길 필요가 없습니다. 하지만 의미는 있어야 합니다. update, fix, asdf보다 feat: build basic todo app이 훨씬 낫습니다. 이번 커밋에는 기본 Todo 앱 기능이 들어갔으므로 feat가 어울립니다.
Codex에게 커밋 메시지를 제안받을 수도 있습니다.
현재 staged changes를 기준으로 적절한 커밋 메시지 3개를 제안해 주세요.
Conventional Commits 스타일로 짧게 작성해 주세요.
본문이 필요하다면 한두 줄만 제안해 주세요.예상 결과는 이런 식입니다.
feat: build local todo app
feat: add todo filtering and persistence
docs: document todo app usage하나의 커밋에 기능과 문서가 같이 들어갔으므로 feat: build local todo app 정도가 무난합니다.
Codex App을 사용한다면 앱 안의 Git 기능으로 커밋, 푸시, PR 생성까지 이어갈 수 있습니다. Codex App은 Git 기능과 worktree 지원을 내장하고 있어 여러 작업의 변경 사항을 검토하고 정리하는 데 유리합니다.1
이번 실습의 전체 프롬프트 흐름
여기까지 온 독자를 위해 이번 장에서 사용한 흐름을 한눈에 정리해 보겠습니다. 실제 프로젝트에서는 아래 순서를 그대로 복사해 써도 됩니다.
1. 계획 요청
바로 코딩하지 말고 파일 구조, 구현 순서, 실행 명령, 확인 방법을 먼저 제안해 주세요.
2. 프로젝트 뼈대 생성
Vite + React + JavaScript 프로젝트 기본 파일만 만들고 제목 화면만 표시해 주세요.
3. 입력 기능 구현
Todo 입력, 추가 버튼, Enter 추가, 빈 입력 방지를 구현해 주세요.
4. 완료/삭제 구현
Todo를 객체로 바꾸고 완료 토글과 삭제 기능을 추가해 주세요.
5. 필터 구현
전체/진행 중/완료 필터 버튼과 현재 선택 스타일을 추가해 주세요.
6. localStorage 연동
앱 로드 시 복원하고 todos 변경 시 저장해 주세요. 손상된 데이터도 방어해 주세요.
7. UI 방어
빈 상태, 긴 텍스트 줄바꿈, 기본 스타일을 개선해 주세요.
8. 테스트 시나리오 생성
브라우저에서 직접 확인할 수 있는 수동 테스트 체크리스트를 만들어 주세요.
9. README 작성
소개, 기능, 설치, 실행, 사용법, 테스트 체크리스트를 문서화해 주세요.
10. 리뷰와 커밋
diff를 확인하고 staged changes 기준으로 커밋 메시지를 제안해 주세요.이 흐름이 Codex 앱 개발의 기본 루프입니다. 계획, 구현, 실행, 확인, 수정, 문서화, 커밋. 앞으로 만들 앱이 커져도 이 순서는 크게 달라지지 않습니다.
초보자가 자주 하는 실수
첫 Todo 앱에서 가장 흔한 실수는 "한 번에 다 해 달라"고 요청하는 것입니다. Codex는 똑똑하지만, 요청이 커질수록 사람이 검토하기 어려워집니다. 결과가 마음에 안 들어도 어디서부터 잘못됐는지 찾기 힘듭니다.
두 번째 실수는 브라우저에서 직접 확인하지 않는 것입니다. Codex가 "구현했습니다"라고 말해도 실제로 버튼을 눌러 봐야 합니다. 앱 개발에서 진실은 브라우저, 터미널, 테스트 결과, diff에 있습니다.
세 번째 실수는 Git 커밋 없이 계속 진행하는 것입니다. 작은 성공 지점에서 커밋하지 않으면 나중에 잘못됐을 때 돌아갈 지점이 없습니다. Codex가 빠르게 많이 바꾸는 시대일수록 Git은 안전벨트입니다.
네 번째 실수는 README를 나중으로 미루는 것입니다. 작은 앱이라도 실행 방법과 기능 목록을 문서로 남기면 프로젝트가 정리됩니다. README를 쓰게 하면 Codex가 현재 프로젝트를 어떻게 이해했는지도 확인할 수 있습니다.
연습 과제: 스스로 한 단계 확장하기
기본 Todo 앱을 완성했다면 다음 중 하나만 골라 확장해 보세요. 모두 한 번에 하지 마세요. 하나를 고르고 새 스레드나 새 브랜치에서 진행하는 것이 좋습니다.
"전체 삭제" 버튼을 추가하되, 누르기 전에 확인 메시지를 띄운다.
남은 할 일 개수를 화면 하단에 표시한다.
Todo를 수정할 수 있는 편집 기능을 추가한다.
localStorage 저장 키를 상수로 분리하고 설명 주석을 추가한다.
수동 테스트 체크리스트를 README에서 별도
docs/manual-test.md로 분리한다.
예를 들어 남은 할 일 개수를 추가하려면 이렇게 요청합니다.
남은 할 일 개수를 표시하는 작은 기능을 추가해 주세요.
대상 파일:
- src/App.jsx
- 필요하면 src/App.css
목표:
- completed가 false인 Todo 개수를 계산해 화면 하단에 보여 주세요.
- 예: "남은 할 일 2개"
제약:
- 기존 Todo 추가, 완료, 삭제, 필터, localStorage 기능을 깨뜨리지 마세요.
- 새 라이브러리를 설치하지 마세요.
완료 기준:
- Todo 추가 시 개수가 증가
- 완료 체크 시 개수가 감소
- 완료 해제 시 개수가 증가
- 삭제 시 개수가 올바르게 반영이 정도 크기의 확장이 좋습니다. 작지만 실제 기능이고, 기존 상태와 연결되며, 검증도 쉽습니다.
하나의 작은 완성 경험
이 장에서 우리는 Todo 앱 하나를 끝까지 만들었습니다. 엄청난 앱은 아니지만, 앱 개발의 핵심 루프는 모두 경험했습니다. 요구사항을 적었고, Codex에게 계획을 먼저 받았고, 작은 작업 단위로 구현했고, 브라우저에서 확인했고, 버그를 증상 중심으로 수정했고, 테스트 시나리오와 README를 만들었고, 마지막으로 Git 커밋까지 했습니다.
이제 Codex를 쓰는 감각이 조금 달라졌을 것입니다. "AI에게 앱을 만들어 달라고 하는 것"이 아니라, "내가 정한 목표를 향해 AI와 함께 작은 변경을 쌓아 가는 것"에 가까워졌을 겁니다.
다음 장에서는 이 흐름을 조금 확장해 날씨 대시보드 앱을 만들어 보겠습니다. Todo 앱은 브라우저 안의 데이터만 다루었지만, 날씨 대시보드는 외부 API, 로딩 상태, 에러 처리, 카드형 UI를 다룹니다. 오늘 익힌 작은 작업 루프가 그대로 다음 단계의 발판이 됩니다.
참고
1Codex App - OpenAI Developers
2Codex 사용법 가이드: 시작 방법, 5가지 팁, 실전 베스트 프랙티스
4Codex App Beginner Guide: Installation, Sandbox, Parallel Tasks, Skills, and MCP
5Codex for (almost) everything - OpenAI
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.