Markdown lists
Lists are the syntax people write most and debug most, because indentation decides everything and indentation is invisible. Here is what each rule actually does.
Updated September 2026
Bullet lists
A hyphen, asterisk or plus followed by a space starts a bullet. All three produce identical output, so the choice is stylistic — hyphens are the most common, and the easiest to see in a raw file.
But the marker is not purely cosmetic in one respect: switching markers mid-list starts a new list. A run of hyphens followed by a run of asterisks renders as two lists with a gap between them, which is occasionally a useful trick and more often an accident. Pick one and stay with it. A blank line above the list is required if a paragraph sits directly on top.
You type
Shopping:
- Bread
- Milk
- CoffeeYou get
Shopping:
- Bread
- Milk
- Coffee
Numbered lists and auto-numbering
A number, a full stop and a space start an ordered list. The numbers you type after the first one are ignored: the renderer counts for you. A list written as 1, 1, 1 renders as 1, 2, 3, and so does one written 1, 7, 4.
This is a feature worth using. Write every line as 1. and you can insert, delete or reorder steps without renumbering anything, and the diff shows only the line that changed. A closing parenthesis works instead of the full stop in most parsers, 1), but the full stop is more portable.
You type
1. Clone the repository
1. Install dependencies
1. Copy the example config
1. Run the test suiteYou get
- Clone the repository
- Install dependencies
- Copy the example config
- Run the test suite
Every line says 1. and the output still counts to 4.
Starting at a number other than one
The first number in the list is the one number that matters — it becomes the list's start value. Begin with 5. and the list runs 5, 6, 7. This is how you continue a sequence that was interrupted by a paragraph, a diagram or a code block that fell outside the list.
One caveat: a paragraph between two lists usually splits them into two lists, and only the second list's first number is honoured. If the numbering has to be continuous across a break, either keep the intervening content inside the list item by indenting it, or set the start number explicitly.
You type
1. Download the installer
2. Run it
Restart before continuing.
3. Sign in
4. Import your dataYou get
- Download the installer
- Run it
Restart before continuing.
- Sign in
- Import your data
Nesting
Indent a child item so it lines up with the text of its parent. Under a bullet written - , that is two spaces. Under a numbered item written 1. , it is three. Four spaces also works for both and is the safest habit if a document has to travel between renderers — the one rule every parser agrees on is that four spaces is deep enough.
Use spaces, never tabs. A tab is often read as an indented code block, which turns your sub-item into grey monospace text. Nesting can mix types freely: a numbered list inside a bullet, a bullet inside a numbered item. Three levels is usually the point at which a list should have been a set of headings instead.
You type
- Backend
- API
- Auth
- Workers
- Frontend
1. Build
2. DeployYou get
- Backend
- API
- Auth
- Workers
- API
- Frontend
- Build
- Deploy
Task lists and checklists
Put [ ] or [x] immediately after the list marker to get a checkbox. This comes from GitHub Flavored Markdown, not from core Markdown, and the spacing is exact: marker, space, bracket, space, bracket, space, text. - [x] is checked; - [X] works too; - [] with no space inside does nothing.
On GitHub, checkboxes in an issue or pull request body are clickable and tick the source file for you, and the progress appears as a counter on the issue. Everywhere else — this viewer included — they render as read-only checkboxes that reflect the state in your text. Task items nest like any other list item.
You type
- [x] Draft the proposal
- [x] Circulate for comments
- [ ] Incorporate feedback
- [ ] Legal
- [ ] Finance
- [ ] SendYou get
- Draft the proposal
- Circulate for comments
- Incorporate feedback
- Legal
- Finance
- Send
Paragraphs and code inside a list item
A list item can hold more than one line. Leave a blank line, then indent the extra content to the item's text column — two spaces under a bullet, three under a numbered item. Everything indented that far belongs to the item, including paragraphs, quotes, tables and fenced code blocks.
The mistake to watch for is indenting the content of a code block but not its fences. Both fence lines must be indented too, or the block ends the list. If a numbered list restarts at 1 immediately after a code block, that is exactly what happened.
You type
1. Install the CLI:
```bash
npm i -g ledger-cli
```
It needs Node 20 or later.
2. Run `ledger init`.You get
-
Install the CLI:
npm i -g ledger-cliIt needs Node 20 or later.
-
Run
ledger init.
Tight lists and loose lists
A list with no blank lines between its items is tight: each item's text is placed directly in the list item, and the rendered list is compact. Put a blank line anywhere between items and the whole list becomes loose: every item is wrapped in a paragraph, and the spacing opens up.
It is all or nothing — one blank line loosens the entire list, not just the gap where you put it. That is the usual explanation for a list that suddenly looks double-spaced. In this viewer it has one extra consequence worth knowing: task list checkboxes are detected on tight items, so a checklist with blank lines between the items renders as literal brackets instead of boxes. Keep checklists tight.
You type
- Tight
- List
* Loose
* ListYou get
- Tight
- List
-
Loose
-
List
Why isn't my list rendering?
No blank line above it. A list directly beneath a paragraph is absorbed into that paragraph. This is the most frequent cause of all.
No space after the marker. -Item is a word; - Item is a list.
The list splits into two. Either the bullet marker changed part-way down, or a block that was meant to sit inside an item was not indented far enough.
Numbers restart at 1. Same cause: something interrupted the list. Indent the interrupting block into the item.
A nested item did not indent. Check for a tab where spaces were needed, or for a single space, which some parsers ignore.
An indented item turned into a code block. Four or more spaces with no parent item above it is code.
Checkboxes show as brackets. The renderer has no task list support, the spacing inside the brackets is wrong, or the list is loose. The GFM guide covers what is core syntax and what is not.
Frequently asked questions
How do I make a checklist in Markdown?
Write a normal bullet and put a bracketed space or an x straight after the marker, like a hyphen, space, open bracket, space, close bracket, space, then the text. The spacing has to be exact.
Why do my numbered list items all show as 1?
Something broke the list into separate one-item lists, usually an unindented paragraph or code block between the items. Indent that content to the item's text column.
How many spaces do I need to indent a nested list?
Two under a bullet, three under a numbered item, matching the parent's text. Four spaces works for both and is the most portable. Never use tabs.
Can I start a numbered list at 5?
Yes. The first number sets the start value, so beginning with 5 gives you 5, 6, 7. The remaining numbers are ignored and counted automatically.
Why is my list double-spaced?
A blank line between any two items makes the whole list loose, so every item is wrapped in a paragraph. Remove the blank lines to get a compact list back.
Are checkboxes clickable in Markdown?
Only where the platform makes them so. GitHub lets you tick boxes in issues and pull requests, which edits the underlying text. Most viewers, including this one, show them read-only.
Indentation problems are obvious the moment the preview sits beside the source.