Task Lists

A task list is a checkbox written in Markdown: - [ ] for something that is still to do, - [x] for something that is finished. It is the form you reach for when a list carries a status rather than just an order, and it looks so much like an ordinary bullet list that it is easy to forget the syntax has a second half. The bracket pair has to sit directly after the marker, and a missing space turns the whole item back into ordinary text with visible brackets.

The second thing to know is that the task list is not part of CommonMark. It is a GitHub Flavored Markdown extension, which means it is widely supported by the tools people actually write in — GitHub, most static site generators, most editors — but not guaranteed everywhere. A renderer that does not implement the extension still shows your list, and the brackets stay visible in the text. This page covers the exact syntax, what may go inside a task item, and the question of when a checklist is the right tool and when an ordinary list is.

The syntax

Put a pair of square brackets directly after the list marker. A space inside the brackets means “not done”, an x means “done”:

- [ ] Write the documentation
- [x] Ship the release
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" disabled> Write the documentation</li>
<li class="task-list-item"><input type="checkbox" checked disabled> Ship the release</li>
</ul>

The list itself is still a <ul>. The difference is the contains-task-list class on it, the task-list-item class on each item, and the <input type="checkbox"> element the renderer injects in front of the text. The disabled attribute on that input is the part worth looking at, and the warning at the end of this page explains why it is there. In a renderer that does not implement the GFM extension the same source produces a plain <li>[ ] Write the documentation</li>, with the brackets visible in the text.

The x is not case sensitive: - [X] produces the same checked box. The brackets carry the state and nothing else, so everything after them is ordinary list item content.

The space after the bracket

The closing bracket must be followed by a space, exactly like the list marker itself:

- [ ] is a task
- [ ]is not a task
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" disabled> is a task</li>
<li>[ ]is not a task</li>
</ul>

The second item is a plain list item, and the brackets are visible in the rendered text. This is the same rule as the space after the marker: the parser has to be able to tell where the marker ends and the content begins, and the space is what tells it.

What may go inside a task item

A task item accepts the same inline content as any other list item — links, code, emphasis — and a task item can hold a nested task list, in which case the checkboxes are indented along with it:

- [ ] Read the [installation guide](https://example.com/install)
- [x] Run `pnpm test` and fix the failures
- [ ] Write the release notes
  - [x] Draft the summary
  - [ ] Ask for a review
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" disabled> Read the <a href="https://example.com/install">installation guide</a></li>
<li class="task-list-item"><input type="checkbox" checked disabled> Run <code>pnpm test</code> and fix the failures</li>
<li class="task-list-item"><input type="checkbox" disabled> Write the release notes
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" checked disabled> Draft the summary</li>
<li class="task-list-item"><input type="checkbox" disabled> Ask for a review</li>
</ul>
</li>
</ul>

The indentation follows the rule from the previous page: a child needs to line up with the column where the parent’s text starts, which for a - marker is two columns in.

Task list or ordinary list

The two forms are not interchangeable, because they carry different information. An ordinary list says “these are the items”; a task list says “these are the items, and each one is either done or not done”.

What you want to expressUse
steps to perform, in orderan ordered list
parallel points, no orderan unordered list
things that can each be done or not donea task list

A checklist in a README, a release plan, or a list of acceptance criteria carries that status, and a reader can see at a glance how far the work has got. A numbered procedure does not carry status at all, and putting checkboxes on the steps of a procedure is misleading: a checkbox in a rendered page is a picture of a state, not a record of one, so it cannot tell a reader whether a step was performed today or is still pending. Use the ordered list for the procedure, and the task list for the backlog.

Common mistakes

Written asActually renders asWhy
- [ ] Taskan unchecked checkboxthe base form
- [ ]Taskplain text with visible bracketsa space must follow the bracket
- [x] Taska checked checkboxthe x is not case sensitive
1. [ ] Taskalso a task listboth markers are supported
a checkbox on the pagecannot be clickedthe input element is disabled

Exercises

Rewrite the following plain text as Markdown. Use a task list for the three items, mark the first one as done, nest two subtasks under the second item with one of the two done, and keep a space between the closing bracket and the text of every item.

Collect the references (done)
Write the chapter
  Draft the outline (done)
  Fill in the examples
Publish the page
Task listsCheckbox stateNested subtasks

Approach:

A task list is an unordered list whose items begin with a bracketed state marker, so the three top-level items keep the dash marker and gain a pair of square brackets. A space inside the brackets means not done and an x means done, and the closing bracket has to be followed by a space. The two subtasks are children of the second item, so they are indented by two spaces and carry their own state markers.

Steps:

  1. Write the three top-level items as a dash, a space, a bracketed state, a space, and the text. Use [x] for the item that is finished and [ ] for the two that are not.
  2. Indent the two subtasks by two spaces, which is the column where the parent item’s text starts under a - marker, and give each of them its own bracketed state.
  3. Keep the same casing for the x throughout the document, even though the renderer accepts both.
  4. Check the result: rendering it must produce three checkbox items, the first one ticked, with two indented checkbox items under the second.

Answer:

- [x] Collect the references
- [ ] Write the chapter
  - [x] Draft the outline
  - [ ] Fill in the examples
- [ ] Publish the page

Summary

You can now write a task list in both its states, and you know that the brackets have to sit directly after the list marker with a space in front of the text, and that a missing space leaves the brackets visible in the output. You know that the syntax is a GFM extension rather than part of CommonMark, so a renderer without it shows plain bracketed text instead of checkboxes. You also know that a task item carries the same content as any other list item and can hold nested tasks, and that the checkbox a reader sees is a picture of a state rather than a control they can click. That is the end of this chapter: the list syntaxes and the quote syntax are complete, and the next chapter moves on to links and images.

Found an issue with this content?

Tell us what could be improved.