Markdown Checkbox Syntax: The Complete Reference (2026)

Markdown checkbox syntax: the `- [ ]` and `- [x]` rules, nesting, where checkboxes render on GitHub, Obsidian, and VS Code, plus the gotchas that break them.

By Ege Beşe10 min read

A markdown checkbox is a task list item from GitHub Flavored Markdown: - [ ] marks an open task and - [x] marks a finished one. The whole syntax is four characters of prefix before your text. Every rule, edge case, and rendering difference that matters is on this page.

- [ ] Open task
- [x] Finished task
  - [ ] Nested subtask

That block is the entire format, and it is also why the format travels so well: there is no app-specific metadata to lose when you move files between editors. The strategic case for running tasks this way lives in our guide to markdown task management, and if you want ready-made files instead of syntax rules, the markdown todo list template post ships five copy-paste lists. This page is the reference: the exact syntax, where markdown checkboxes render, and the mistakes that break them.

Overhead flat-lay of a warm-paper desk with an open gridded notebook showing a neat column of small empty squares with a single square filled in dark, a fountain pen resting beside.
One filled square is the whole idea.

What is the exact markdown checkbox syntax?

The markdown task list syntax is a hyphen, one space, an opening bracket, one space or one lowercase x, a closing bracket, one more space, then the task text. - [ ] buy milk renders as an open checkbox. - [x] buy milk renders as a checked one. Everything else is a variation that fails.

Worth knowing in detail:

  • The hyphen can also be an asterisk in some renderers (* [ ] task), but the hyphen is the safe default because every GFM-compatible tool accepts it.
  • GitHub also accepts an uppercase X (- [X] task) and renders it as checked. Other tools are less consistent, so lowercase x is the portable choice.
  • The brackets must contain exactly one character: one space, or one x. [x ], [ X], and [] all render as plain text.
  • The character after the closing bracket must be a space. - [ ]task (no space) does not render as a checkbox on GitHub or in Obsidian.
- [ ] Open task
- [x] Done task
- [X] Also done on GitHub, not portable everywhere

Where do markdown checkboxes render, and which ones are clickable?

Markdown checkboxes render on GitHub, in Obsidian, in VS Code's markdown preview, and in Typora, Bear, and most editors shipped since about 2020. They are clickable only where the app wires the rendered box back to the source text: GitHub issues, pull requests, and comments, plus Obsidian's reading view and live preview. Everywhere else they are static.

Rendering and interactivity by app

The quick version before the details:

AppRenders checkboxClickable
GitHub issues, PRs, commentsYesYes, edits source text
GitHub README and file previewsYesNo, static display
ObsidianYesYes, in reading view and live preview
VS Code markdown previewYesNo, extension adds a source toggle
Typora, BearYesYes, in the rendered view

The interactive versus static split matters more than it looks. On GitHub, checking a box in an issue rewrites the markdown source, so the checkbox is a real edit surface. In a README preview the same box is display-only, which means a task list in a README is documentation, not a working list. As of 2026, that split is unchanged across the major tools.

How do you nest subtasks in a markdown task list?

Nest a subtask by indenting its line two or four spaces under the parent, keeping the same checkbox syntax. Two spaces renders correctly in most tools, and four spaces works everywhere, including stricter CommonMark-based renderers. Always indent with spaces, never tabs.

- [ ] Ship the onboarding redesign
  - [ ] Draft the empty states
  - [ ] Record the 30-second demo clip
    - [ ] Book the quiet room
- [ ] Send the changelog to the newsletter list

The nesting is visual only. Markdown checkboxes carry no real hierarchy, so completing a parent does not complete its children, and no renderer will roll up progress for you. GitHub does count checkboxes in issues and pull requests and shows a progress bar, but it counts every checkbox in the body as a flat list, nested or not.

Is the markdown checkbox part of core markdown?

No. John Gruber's original 2004 markdown spec has no task list syntax, and the CommonMark standard, which formalized markdown in 2014, does not include one either. Task lists are a GitHub Flavored Markdown extension that GitHub introduced in 2014, and the rest of the ecosystem adopted the extension afterward.

The practical consequence: if a tool advertises "CommonMark compliant" and nothing more, assume no checkboxes until you see one render. If a tool says "GFM" or "GitHub Flavored Markdown," the checkbox syntax in this reference will work.

Which markdown checkbox mistakes break rendering?

Three mistakes account for almost every broken checkbox: a missing space in the - [ ] prefix, a checkbox placed outside a list item, and tab-indented subtasks. The prefix rules are strict, the list-only rule is part of the GFM spec, and tabs are a per-editor setting that looks aligned in one app and breaks in the next.

The gotchas table

You typedWhat happensFix
-[ ] taskLiteral text, not a listSpace after the hyphen
- [] taskLiteral bracketsOne space inside brackets
- [ ]taskLiteral bracketsSpace after closing bracket
- [x ] taskLiteral bracketsExactly one character inside
## - [ ] taskHeading text, not a checkboxMove it to a list item
Tab-indented subtaskBreaks nesting in some editorsIndent with two or four spaces

How do markdown checkboxes hold up in a real task system?

Markdown checkboxes hold up well for storage and portability, and poorly for capture. A folder of markdown files with - [ ] lines is greppable, Git-versioned, and readable in every editor for the next several decades. The failure mode is the moment of capture: typing - [ ] on a phone keyboard, or hunting for the right file mid-thought, is where plain-text systems quietly die.

That is the gap quik.md is built for. You speak the thought out loud, the AI organize step files it into the right project and writes the next step, and everything exports as plain markdown, so quik and your files never fight over who owns the data. quik is a PWA, the free plan covers a daily AI-organize cap with browser speech recognition, and Pro is $14.99 monthly or $69.99 yearly with a 7-day trial, or $99.99 once for lifetime. If hand-maintaining files works for you, keep the files. If capture is where the system breaks, our page on voice to markdown walks through the workflow, and the pillar on AI task managers maps where quik sits in the category.

Pricing shown reflects plans at the time of writing. Check quik.md/pricing for current rates.

FAQ

What is the markdown checkbox syntax?

The markdown checkbox syntax is - [ ] for an open task and - [x] for a completed one, placed at the start of a list item. It comes from GitHub Flavored Markdown, not core markdown. Hyphen, one space, brackets with one space or one x inside, one more space, then the task text.

Why is my markdown checkbox not rendering?

The most common cause is a spacing error: - [ ] task renders, but -[ ] task, - [ ]task, and - [] task do not. The second cause is context, because checkboxes only work as list items. Inside a heading, a blockquote, or a code fence, the same characters stay literal text.

Can you click markdown checkboxes on GitHub?

In GitHub issues, pull requests, and comments, yes. The rendered checkbox is clickable, and clicking it edits the source text by flipping the space to an x. In README files and other rendered markdown file previews, the same checkboxes display as static and cannot be clicked.

Does the markdown checkbox work in Obsidian and VS Code?

Yes in both, with caveats. Obsidian renders - [ ] and - [x] as clickable checkboxes in reading view and live preview. VS Code's built-in markdown preview renders them as static checkboxes, and the Markdown All in One extension adds a shortcut to toggle them in the source.

How do you indent subtasks in a markdown task list?

Indent the subtask line two or four spaces under its parent and keep the same checkbox syntax. Two spaces works in most renderers, four spaces works everywhere. Always use spaces, never tabs, because tab width is a per-editor setting and can silently break the nesting.

References

ShareShare on X

Keep reading