·7분 읽기
마크다운 체크박스 목록 작성법 — GitHub Todo List 실전 문법
마크다운 체크박스 문법과 깃허브·노션·옵시디언 호환 방법을 정리했어요. 중첩 체크리스트, 진행률 표시, 실전 PR 템플릿까지 다뤘습니다.

마크다운 체크박스 기본 문법
GFM(GitHub-Flavored Markdown)에서 체크박스 문법은 단순해요.
- 하이픈 + 공백 + 대괄호 공백 + 공백 = 미완료 항목
- 하이픈 + 공백 + 대괄호 안에 x = 완료된 항목
대괄호 안의 공백은 미완료, 소문자 x는 완료예요. 대문자 X도 인식되지만 소문자가 관례거든요. asterisk(*)나 plus(+)를 쓴 리스트 마커도 똑같이 동작해요.
주의할 점은 대괄호 양옆 공백이에요. 여기를 빼먹으면 그냥 텍스트로 렌더링돼요. 또 줄 시작에 들여쓰기가 없어야 최상위 체크박스로 잡혀요. 너무 많이 들여 쓰면 코드 블록으로 인식되거나 부모 항목의 하위로 잡혀요.
중첩 체크리스트
상위 작업 안에 세부 작업을 넣으려면 들여쓰기를 써요.
예시
- 프로젝트 셋업 (미완료)
- 저장소 생성 (완료)
- Next.js 설치 (완료)
- ESLint 설정 (미완료)
- 배포 (미완료)
- Cloudflare Pages 연결
- 도메인 연결
- 환경 변수 설정
들여쓰기는 스페이스 2개 또는 4개가 표준이에요. 탭은 렌더러마다 해석이 달라서 깨지기 쉬워요. VSCode 설정에서 'Insert Spaces'를 체크해 두세요.
중첩 깊이는 3단계까지가 가독성 한계예요. 그 이상은 별도 문서로 분리하거나, 부모를 별개 섹션으로 빼는 게 나아요.
호환되는 렌더러
체크박스는 GFM 확장 문법이라 모든 마크다운에서 되는 건 아니에요.
**지원**
- GitHub Issues·PRs·README
- GitLab Issues·MRs
- Bitbucket
- Notion(체크박스 블록으로 자동 변환)
- Obsidian(클릭 토글까지 지원)
- Typora
- VSCode Markdown Preview
- Toolkio Previewer
**기본 미지원(플러그인 필요)**
- 순정 CommonMark
- 구버전 Jekyll(remark-gfm 추가 필요)
- 기본 Docusaurus(remark-checkbox 플러그인)
- 티스토리·블로그 기본 에디터
미지원 환경이라면 HTML `<input type="checkbox" disabled>` 태그로 직접 작성하면 되긴 하지만 글이 지저분해져요. 운영 글은 GFM 지원 플랫폼에 맞춰 쓰는 게 편해요.
진행률 표시하기
GitHub Issue·PR 본문에서는 체크 개수를 자동으로 세서 '3 of 5 tasks completed' 같은 표시를 보여줘요. 별도 설정 없이 그냥 작동해요.
외부 README나 블로그에서 진행률 뱃지를 넣고 싶으면 shields.io를 활용하세요.
예시: 
마일스톤별 진행률을 보여줄 때
- 백엔드 API ████████░░ 80%
- 프론트엔드 UI ██████░░░░ 60%
- 테스트 ████░░░░░░ 40%
유니코드 블록 문자(█·░)로 ASCII 진행률 바도 만들 수 있어요. README에 시각적인 진행 상황을 넣으면 협업자들이 한눈에 파악해요.
실전 PR 템플릿
깃허브 Pull Request 템플릿 예시예요. `.github/pull_request_template.md`에 저장하면 PR 작성 시 자동으로 본문에 들어가요.
**변경 사항(Why)**
- 한 줄 요약: 무엇을 왜 바꾸었는지
**구현 체크리스트**
- [ ] 로컬에서 빌드 성공
- [ ] 단위 테스트 추가/수정
- [ ] 관련 이슈 #번호 링크
- [ ] 리뷰어 지정
- [ ] UI 변경 시 스크린샷 첨부
**배포 주의사항**
- [ ] 환경 변수 추가 여부
- [ ] DB 마이그레이션 필요 여부
- [ ] 롤백 계획 정리
**문서·후속**
- [ ] README 업데이트
- [ ] 변경 로그 추가
- [ ] Slack #release 공지
매번 같은 체크리스트가 자동 삽입돼서 빠뜨리는 일이 줄어요. 팀 단위 도입하면 코드 리뷰 시간이 30% 정도 단축되거든요. 리뷰어가 '뭘 봐야 할지' 명확해지니까요.
체크박스 활용 시나리오
PR 템플릿 외에도 활용처가 많아요.
**Issue 템플릿(버그 리포트)**
- [ ] 재현 단계 명시
- [ ] 기대 동작 vs 실제 동작
- [ ] 환경(OS·브라우저·버전) 정보
- [ ] 스크린샷 또는 로그
**프로젝트 README 로드맵**
- [x] v1.0 — 기본 기능
- [x] v1.1 — 다국어 지원
- [ ] v1.2 — 다크 모드
- [ ] v2.0 — 플러그인 시스템
**Daily Standup**
- [x] 어제 한 일
- [ ] 오늘 할 일
- [ ] 블로커
**개인 Todo(Obsidian·Notion)**
- [ ] 오전: 회의 자료 정리
- [ ] 오후: 코드 리뷰 3건
- [x] 점심: 운동 30분
Obsidian에서는 체크박스 클릭으로 토글이 돼서 그냥 메모장에 가까운 사용감이에요. 매일 쓰는 데일리 노트에 체크박스 템플릿 박아두면 편해요.
Toolkio Markdown Previewer로 확인
체크박스를 작성하면서 바로 렌더링을 확인할 수 있어요. GFM 모드를 켜면 체크박스가 활성화된 상태로 표시돼요.
사용 흐름은 단순해요.
1. 왼쪽 입력 영역에 마크다운 작성
2. 오른쪽에 실시간 미리보기
3. 체크박스·중첩 들여쓰기·진행률까지 즉시 확인
4. HTML 복사 버튼으로 결과를 클립보드에
옵시디언처럼 클릭 토글까지는 안 되지만, 렌더링 결과를 HTML로 복사해서 티스토리·네이버 블로그·구글 닥스에 붙일 때 편해요. PR 템플릿 작성하기 전에 미리보기로 들여쓰기 깊이·체크박스 정렬 검증하시면 실수가 줄어요.
Obsidian·노션·Logseq 체크박스 비교
체크박스는 같은 마크다운 문법이라도 도구마다 동작이 미묘하게 달라요. 자주 쓰는 세 도구를 비교해 둘게요.
**Obsidian(1.5+ 기준)**
- 클릭 토글 기본 지원, 키보드 `Ctrl/Cmd + Enter`로도 토글 가능
- 'Tasks' 커뮤니티 플러그인 설치하면 마감일·반복·우선순위 메타데이터까지 인라인으로 박을 수 있어요
- 예시: `- [ ] 보고서 작성 📅 2026-05-15 ⏫`
- 모든 노트의 미완료 작업을 Dataview 쿼리로 모아보기 가능
- 로컬 마크다운 파일이라 Git 동기화·버전 관리 자연스러움
**Notion**
- '체크박스 블록'은 사실 마크다운 체크박스가 아니라 Notion 자체 블록 타입이에요
- 마크다운 import 시 `- [ ]` → 체크박스 블록 자동 변환
- 페이지 export 시 마크다운으로 다시 변환되긴 하지만 일부 메타데이터(생성자·수정시각)는 손실
- 데이터베이스에 'Checkbox' 속성을 두면 별도 블록 없이 row마다 체크 가능, 필터·정렬 자유로움
- 협업 기능(멘션·댓글·실시간 편집)은 가장 강력
**Logseq**
- 'TODO/DOING/DONE' 워크플로우가 빌트인 — 단순 체크박스보다 상태 단계가 많음
- 키보드 `Ctrl + Enter`로 상태 순환(`TODO` → `DOING` → `DONE`)
- 마감일은 `SCHEDULED: <2026-05-15>` 같은 Org-mode 스타일로 입력
- 그래프 뷰로 작업 사이 관계 시각화
- 로컬-퍼스트, Obsidian과 비슷하지만 블록 단위 데이터베이스 모델이 더 강함
선택 기준은 단순해요. 혼자 깊은 학습 노트·연구 노트면 Obsidian이나 Logseq, 팀 협업이면 Notion이에요. 셋 다 GFM 체크박스 문법은 호환되니까 작성 자체는 어디서 해도 되고, 저장소만 정해 두세요.
체크리스트 안티패턴 — 운영 중에 자주 깨지는 패턴
체크리스트는 좋은 도구지만 잘못 운영하면 오히려 일을 늦추거나 흐지부지하게 만들어요. 자주 보이는 안티패턴 5개를 정리했어요.
**1. 체크박스만 50개, 본문 없음**
작업 항목만 줄줄이 박아두고 'why' 설명이 없으면 며칠 지나서 본인도 무슨 작업인지 못 알아봐요. 항목 한 줄당 30초 이내에 의도가 떠올라야 해요. 안 떠오르면 한 줄로 컨텍스트를 추가하세요.
**2. 같은 PR에서 체크박스 수십 개 토글**
리뷰어 입장에서 '이 PR은 다 끝난 건가, 아닌가' 판단이 안 돼요. 체크박스는 작업 시작 전에 프리필하고, 끝난 항목은 PR description 갱신으로 표시하세요. GitHub는 description 수정 이력도 남아서 토글 시점이 추적돼요.
**3. 끝낼 수 없는 항목 박아두기**
'전체 코드베이스 리팩토링' 같은 항목이 체크리스트에 들어가면 영원히 미완료로 남아요. 체크박스는 1~3시간 안에 끝낼 수 있는 단위로 쪼개세요. 더 큰 작업은 Issue로 분리하고 체크리스트에서는 링크만 박는 게 깔끔해요.
**4. 체크 후 삭제**
끝낸 항목을 지워 버리면 회고할 때 '뭐 했지' 기억 안 나요. 체크 표시로 남겨두는 게 누적 성취감에 도움이 돼요. Obsidian의 일일 노트 패턴이 좋은 예 — 체크된 항목을 다음 날 노트에 자동으로 합치지 않고 그날 노트에 그대로 남겨요.
**5. 우선순위 없이 평면 나열**
10개 항목이 다 같은 들여쓰기로 박혀 있으면 어디부터 손댈지 판단 못 해요. 'P0(오늘) / P1(이번 주) / P2(언젠가)' 같은 그룹 헤더를 한 줄 추가하거나, 별표 이모지로 시각적 무게를 다르게 주세요.
마크다운 체크박스가 깨질 때 디버깅 흐름
GFM 문법이 분명히 맞는데 체크박스가 텍스트로만 보이면 어디부터 점검해야 할지 막막해요. 자주 보이는 원인 순서대로 정리했어요.
**1. 렌더러 GFM 모드 확인**
첫째 의심은 사용 중인 마크다운 엔진이 GFM 확장을 켰는가예요. 순정 CommonMark 라이브러리(예: marked, markdown-it 기본 설정)는 체크박스를 인식 안 해요. 해결책은 두 가지 — `markdown-it` + `markdown-it-task-lists` 플러그인을 추가하거나, GFM 기본 지원하는 `remark-gfm`(unified.js 생태계)을 쓰세요. 정적 사이트 생성기(Astro·Docusaurus·Next.js)는 보통 plugin 형태로 노출돼 있으니까 config 한 줄만 추가하면 돼요.
**2. 들여쓰기·공백 문제**
`-[ ]` (하이픈 뒤 공백 누락) 또는 `- []` (대괄호 안 공백 누락)는 체크박스로 인식 안 돼요. 정확한 형태는 `- [ ] ` — 하이픈, 공백, 대괄호 안에 공백 1개, 닫는 대괄호, 공백 1개, 그 다음 본문. 또 들여쓰기가 4칸 이상이면 코드 블록으로 인식돼서 체크박스가 안 보여요.
**3. CRLF vs LF 줄바꿈**
Windows에서 작성한 마크다운이 macOS·Linux 환경의 빌드에서 깨지는 경우 줄바꿈 문자가 원인일 때가 있어요. CRLF(Windows)는 일부 파서에서 빈 줄로 안 잡혀서 리스트 그룹이 깨져요. `.gitattributes`에 `*.md text eol=lf` 한 줄 추가해서 통일하세요.
**4. HTML 이스케이프**
사용자 입력을 받아 마크다운으로 렌더링하는 댓글·게시판 시스템에서, 보안 차원에서 `[`나 `]`를 HTML entity로 이스케이프하는 경우가 있어요. 그러면 `[ ]`로 변환돼서 체크박스 문법이 깨져요. 화이트리스트 방식 sanitization 라이브러리(DOMPurify·sanitize-html)를 쓰고, GFM 문법은 통과시키도록 설정하세요.
**5. 캐싱**
드물지만 정적 사이트 빌드 캐시가 오래된 HTML을 들고 있어서 새로 추가한 체크박스가 안 보일 때가 있어요. CDN 퍼지·로컬 `.next/cache`·`.docusaurus` 캐시 삭제 후 재빌드. 빌드 직후 라이브 사이트에서 한 번 검증하면 안전해요.