프로그래밍 경험이 없어도 첫 AI 코딩 프로젝트는 시작할 수 있습니다. 기능을 크게 잡지 말고 입력·목록·완료·저장 네 동작만 가진 습관 트래커를 만든 뒤, 실제 브라우저에서 한 단계씩 검증하면 됩니다.
첫 프로젝트로 습관 트래커를 고른 이유
처음부터 로그인, 결제, 데이터베이스, 외부 API가 필요한 서비스를 만들면 무엇이 잘못됐는지 구분하기 어렵습니다. 반면 습관 트래커는 사용자가 문장을 입력하고, 목록에 새 항목이 생기고, 체크박스를 누르면 완료 상태와 진행률이 바뀌는 과정을 한 화면에서 볼 수 있습니다. 새로고침 뒤에도 내용이 남는지 확인하면 브라우저 저장까지 배울 수 있습니다.
이번 프로젝트의 완성 조건은 화면이 예뻐 보이는 것이 아니라 관찰 가능한 네 가지 동작입니다. 첫째, “AI 코딩 20분”을 입력하면 목록이 2개에서 3개로 늘어납니다. 둘째, 새 항목의 체크박스를 누르면 완료 스타일이 적용됩니다. 셋째, 진행률이 0/3에서 1/3으로 바뀝니다. 넷째, 페이지를 다시 열어도 세 항목과 완료 상태가 유지됩니다. 이 조건을 먼저 적어 두면 AI가 만든 코드를 평가할 기준이 생깁니다.
프로젝트 파일은 index.html, styles.css, app.js 세 개로 제한했습니다. 빌드 도구와 외부 패키지는 사용하지 않았습니다. 학습 목표가 화면 구조, 스타일, 상태 변경, 저장을 구분하는 것이기 때문입니다. 첫 프로젝트에서 도구 수를 늘리면 설치 오류와 코드 오류가 섞여 원인을 찾기 더 어려워질 수 있습니다.
AI에게 요청하기 전에 요구사항을 네 줄로 쓴다
“습관 앱 만들어 줘”처럼 짧은 요청은 자유도가 너무 큽니다. 화면 모양은 나올 수 있어도 저장 방식, 빈 입력 처리, 진행률 계산, 모바일 동작이 빠질 수 있습니다. 처음 요청에는 사용자가 하는 행동, 화면이 바뀌는 결과, 저장 위치, 실패 조건을 함께 적는 편이 좋습니다.
- 입력: 40자 이내의 습관 이름을 입력하고 추가 버튼을 누른다.
- 상태: 새 항목이 목록 끝에 나타나고 총개수가 즉시 바뀐다.
- 완료: 체크박스를 누르면 완료 개수와 진행 막대가 갱신된다.
- 저장: 항목과 체크 상태를 같은 출처의 브라우저 저장소에 보관한다.
여기에 접근성 조건도 더했습니다. 입력란은 “습관 이름” 레이블과 연결하고, 목록에는 “오늘의 습관 목록”이라는 이름을 붙이며, 저장 결과와 진행 상태는 보조기술이 읽을 수 있는 aria-live 영역으로 알리도록 했습니다. 버튼 색상이나 화면 좌표가 아니라 이름과 역할로 요소를 찾을 수 있게 만드는 조건입니다.
프롬프트는 한 번에 모든 세부 디자인을 요구하지 않았습니다. 먼저 HTML 구조와 상태 변경을 구현하고, 브라우저에서 동작을 확인한 다음 반응형 레이아웃과 색상을 보완했습니다. 수정할 때는 “전체를 다시 만들어 줘”보다 “현재 입력·저장 동작은 유지하고 760px 이하에서 두 카드를 한 열로 배치해 줘”처럼 보존할 동작과 바꿀 범위를 함께 적었습니다.
HTML·CSS·JavaScript를 역할별로 나누기
HTML은 의미와 순서를 담당합니다. 제목, 설명, 입력 레이블, 버튼, 진행률, 목록을 문서에 배치합니다. 입력란의 id와 레이블의 for를 같은 값으로 연결하면 사용자가 레이블을 눌러도 입력란에 초점이 이동합니다. 목록은 동적으로 바뀌지만 비어 있는 컨테이너를 HTML에 미리 두고 JavaScript가 항목을 추가하도록 구성했습니다.
CSS는 화면 표현을 담당합니다. 데스크톱에서는 입력 카드와 목록 카드를 두 열로 놓고, 작은 화면에서는 한 열로 쌓습니다. 완료된 항목에는 배경색과 취소선을 함께 적용해 색상 하나에만 의존하지 않게 했습니다. 진행 막대에는 부드러운 변화가 있지만 사용자가 움직임 감소 설정을 켠 환경에서는 전환 효과를 끄도록 했습니다.
JavaScript는 데이터와 행동을 담당합니다. 습관 배열에는 식별자, 이름, 완료 여부를 보관합니다. 폼의 submit 이벤트에서는 페이지 새로고침을 막고, 공백을 제거한 입력값이 있을 때만 배열에 새 항목을 추가합니다. 체크박스의 change 이벤트에서는 해당 항목의 완료 값을 바꾼 뒤 저장과 화면 갱신을 다시 실행합니다.
MDN addEventListener 문서에서 이벤트 대상에 여러 종류의 이벤트 처리기를 등록하는 기본 동작을 확인했습니다. 이번 앱에서는 폼 제출, 체크박스 변경, 초기화 버튼 클릭을 서로 다른 처리기로 분리했습니다. 하나의 큰 함수 안에 입력, 저장, 화면 갱신을 모두 섞지 않으면 어느 단계에서 문제가 생겼는지 찾기 쉽습니다.
직접 실행한 테스트 환경과 시작 화면
테스트 날짜: 2026년 9월 10일. 환경: Windows 11, Chrome 기반 브라우저, 1265×889 화면, localhost 정적 웹 서버. 초기 데이터: “물 한 잔 마시기”, “10분 걷기” 두 항목. 입력값: “AI 코딩 20분”. 성공 결과: 총 3개 중 1개 완료, 약 33% 진행 막대, 새로고침 뒤 같은 상태 유지입니다.
실행 전 화면에서 “습관 이름” 텍스트 상자와 “습관 추가” 버튼이 각각 한 개씩 존재하는지 확인했습니다. 목록에는 체크되지 않은 기본 항목 두 개가 있었고 진행률은 0/2였습니다. 외부 네트워크 요청, 로그인, 쿠키, 계정 정보, 분석 코드가 없는 로컬 페이지에서 테스트했습니다.
텍스트 상자에 “AI 코딩 20분”을 넣고 추가 버튼을 눌렀습니다. 안내 문구가 새 습관을 추가했다는 내용으로 바뀌었고 목록의 세 번째 항목에 같은 문장이 표시됐습니다. 총개수는 0/2에서 0/3으로 바뀌었습니다. 입력란은 다음 항목을 적을 수 있도록 빈 값으로 돌아갔습니다.
추가·완료·저장을 실제로 검증한 결과
새로 추가된 “AI 코딩 20분 완료” 체크박스가 정확히 한 개임을 확인한 뒤 클릭했습니다. 체크 상태가 참으로 바뀌고 해당 행에 완료 스타일이 적용됐습니다. 진행률 텍스트는 1/3, 완료된 행의 개수는 1개, 전체 행의 개수는 3개로 관찰됐습니다. 화면만 보고 추측하지 않고 DOM의 현재 값과 표시 문구를 함께 확인했습니다.
작동 영상은 같은 브라우저 세션에서 완료 전후 화면을 약 0.25초 간격으로 기록해 연결했습니다. 체크 직후 진행 막대가 약 33%까지 늘어나고 목록의 새 항목이 완료 표시로 바뀌는 흐름을 보여 줍니다. 영상 촬영 뒤 같은 URL을 다시 열었을 때도 습관 3개, 완료 1개, 체크 상태가 유지됐습니다.
저장은 MDN localStorage 문서의 범위에 맞춰 구현했습니다. 같은 출처에서 브라우저 세션을 넘어 문자열 데이터를 보관할 수 있으므로 배열을 JSON 문자열로 변환해 저장하고, 페이지가 열릴 때 다시 배열로 해석했습니다. 저장된 값이 깨졌거나 배열이 아니면 기본 두 항목으로 돌아가도록 예외 처리했습니다.
오류가 생겼을 때 한 단계씩 고치는 순서
추가 버튼을 눌러도 목록이 늘지 않을 때: 폼의 제출 이벤트가 연결됐는지, 기본 새로고침을 막았는지, 입력값의 공백을 제거한 뒤 빈 문자열을 거르는지 확인합니다. 오류 설명에는 버튼을 누른 순서, 입력값, 기대 결과, 실제 결과, 콘솔 메시지를 함께 적습니다.
체크해도 진행률이 바뀌지 않을 때: 체크박스가 배열의 어느 항목과 연결되는지, 변경 뒤 저장 함수와 화면 갱신 함수가 모두 호출되는지 확인합니다. 완료 개수는 전체 배열에서 completed가 참인 항목을 세어 계산해야 합니다. 화면 폭이나 진행 막대 스타일만 바꾸고 실제 완료 개수를 갱신하지 않는 실수를 구분해야 합니다.
새로고침 후 목록이 사라질 때: 저장할 때와 읽을 때 같은 키를 사용하는지, JSON 변환이 실패하지 않았는지, 브라우저가 사이트 데이터 저장을 막고 있지 않은지 확인합니다. file://로 직접 연 문서는 저장 동작이 브라우저마다 달라질 수 있으므로 이번 테스트처럼 localhost 서버에서 확인하는 편이 낫습니다.
같은 항목이 반복 추가될 때: 이번 최소 앱은 중복 이름을 허용합니다. 중복을 막으려면 대소문자와 앞뒤 공백을 정규화한 값으로 기존 배열을 검사하는 조건을 추가해야 합니다. 그러나 기능을 넣은 뒤에는 “물 한 잔 마시기”와 “물 한잔 마시기”처럼 의미는 비슷하지만 문자열이 다른 경우를 어떻게 다룰지도 결정해야 합니다.
첫 프로젝트를 다음 단계로 확장하는 로드맵
첫 번째 확장은 삭제 기능이 아니라 테스트입니다. 빈 입력이 거부되는지, 세 번째 항목이 추가되는지, 체크 뒤 진행률이 1/3인지, 새로고침 뒤 값이 남는지 네 가지 검사를 먼저 자동화하면 다음 수정에서 기존 동작이 깨졌는지 빠르게 알 수 있습니다. 기능 수보다 현재 동작을 재현 가능하게 고정하는 일이 우선입니다.
두 번째 확장은 데이터 구조입니다. 날짜별 습관을 구분하고 지난 기록을 보려면 현재 배열에 날짜와 생성 시각을 추가할 수 있습니다. 이때 기존에 저장된 데이터가 새 구조와 다를 수 있으므로 변환 규칙이 필요합니다. 구조를 갑자기 바꾸면 사용자가 저장한 목록을 읽지 못할 수 있습니다.
세 번째 확장은 서버 동기화입니다. 여러 기기에서 같은 목록을 쓰려면 인증, 데이터베이스, 권한 검사가 필요합니다. 로컬 저장 값을 그대로 서버에 보내는 것만으로는 충분하지 않습니다. 사용자별 데이터 분리, 입력 검증, 전송 암호화, 백업, 삭제 요청 처리까지 범위가 크게 늘어나므로 별도 프로젝트로 다루는 편이 안전합니다.
네 번째 확장은 배포입니다. 정적 호스팅에 올릴 때는 HTTPS, 캐시, 오류 페이지, 모바일 화면, 접근성, 개인정보 안내를 확인합니다. 로컬에서 작동했다는 사실만으로 공개 서비스 운영 준비가 끝난 것은 아닙니다. 배포 후 실제 주소에서 저장 범위와 브라우저 호환성을 다시 검사해야 합니다.
한계와 주의사항
이번 결과는 학습용 로컬 웹앱입니다. 계정, 서버 백업, 기기 간 동기화, 알림, 통계, 데이터 내보내기, 삭제 복구를 제공하지 않습니다. 사용자가 브라우저 사이트 데이터를 지우거나 사생활 보호 모드를 닫으면 값이 사라질 수 있습니다. 건강 기록, 금융 정보, 비밀번호 같은 민감정보를 이 방식으로 저장해서는 안 됩니다.
화면 두 장과 3초 영상은 입력·추가·완료·저장 흐름을 확인한 증거이지만 장기간 사용 안정성을 증명하지 않습니다. 습관이 수백 개일 때의 성능, 다양한 모바일 브라우저, 키보드만 사용하는 조작, 화면 낭독기별 읽기 결과는 후속 테스트가 필요합니다. 저장 공간이 가득 차거나 사용자가 저장을 차단한 경우도 별도로 처리해야 합니다.
AI가 만든 코드는 설명이 자연스럽더라도 오류가 있을 수 있습니다. 코드를 붙여 넣은 뒤 화면이 뜨는 것만 보지 말고 요구사항에 적은 입력, 상태 변화, 저장, 실패 조건을 직접 반복해야 합니다. 외부 패키지를 추가한다면 공식 문서, 라이선스, 유지보수 상태와 알려진 보안 문제를 따로 확인해야 합니다.
결론: 작게 만들고 실제 결과로 확인한다
첫 AI 코딩 프로젝트에서 가장 중요한 것은 거대한 아이디어가 아니라 완료 여부를 직접 판정할 수 있는 작은 범위입니다. 입력, 목록, 완료, 저장을 각각 요구사항으로 나누고 브라우저에서 관찰한 값으로 확인하면 프로그래밍 경험이 적어도 수정 방향을 설명할 수 있습니다.
프롬프트를 어떻게 관찰 가능한 요구사항으로 바꾸는지 더 보고 싶다면 프롬프트로 타이머 웹앱을 만든 실전 글을 함께 확인할 수 있습니다. 다음 단계에서는 이번 습관 트래커에 자동 검사를 추가해, AI가 코드를 수정해도 기존 네 동작이 유지되는지 확인하는 과정을 다룰 예정입니다.