Skip to content
ViewMarkdown

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
- Coffee

You 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 suite

You get

  1. Clone the repository
  2. Install dependencies
  3. Copy the example config
  4. 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 data

You get

  1. Download the installer
  2. Run it

Restart before continuing.

  1. Sign in
  2. 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. Deploy

You get

  • Backend
    • API
      • Auth
    • Workers
  • Frontend
    1. Build
    2. 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
- [ ] Send

You 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

  1. Install the CLI:

    npm i -g ledger-cli
    

    It needs Node 20 or later.

  2. 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

* List

You 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.

Try a checklist in the editor

Indentation problems are obvious the moment the preview sits beside the source.