Layerbit
Documentation

Markdown Cheat Sheet: GitHub-Flavored Syntax With Examples

Markdown is the format of README files, documentation sites, issue trackers, chat apps and note-taking tools. The core syntax fits on a page, but the details that trip people up, such as line breaks, nested lists, tables and escaping, differ between the original specification, CommonMark and GitHub-Flavored Markdown. This sheet shows the syntax that renders the same everywhere, marks the extensions that do not, and explains the rules behind the surprises.

The short version

  • Separate paragraphs, lists, headings and code blocks with a blank line. Most "it didn't render" problems are a missing blank line.
  • A single line break inside a paragraph is ignored; end the line with a backslash or two spaces to force a break.
  • Fenced code blocks (three backticks plus a language name) are the reliable way to show code.
  • Tables, task lists, strikethrough and automatic links are GitHub-Flavored Markdown extensions, supported by most modern renderers.
  • Escape any special character with a backslash: \*, \_, \#, \|.

Markdown, CommonMark and GFM

John Gruber's original Markdown of 2004 was a short description plus a Perl script, and it left many cases ambiguous, so every implementation behaved slightly differently. CommonMark, first published in 2014, is a precise specification with hundreds of examples that resolves those ambiguities; most serious parsers now follow it. GitHub-Flavored Markdown (GFM) is CommonMark plus a small set of extensions: tables, task lists, strikethrough, extended autolinks and filtering of some raw HTML. When this sheet says something works "everywhere", it means CommonMark; GFM extensions are labelled.

Text and headings

You typeResultNotes
# Heading 1 … ###### Heading 6Six heading levelsA space after the # is required in CommonMark
**bold** or __bold__boldAsterisks also work mid-word; underscores do not
*italic* or _italic_italic
***bold italic***bold italic
~~struck~~struckGFM extension
`inline code`inline codeUse double backticks to include a backtick: `` a`b ``
> quoted textBlock quoteNest with > >
--- on its own lineHorizontal ruleNeeds a blank line above, or it turns the previous line into a heading

That last note is a classic surprise. A line of text followed directly by --- becomes a level-2 heading (a "setext" heading), and one followed by === becomes level 1. Leave a blank line before a horizontal rule.

Paragraphs and line breaks

Markdown joins consecutive lines into one paragraph, so text wrapped at 80 columns in the source still flows as a paragraph. Start a new paragraph with a blank line. To force a line break without a new paragraph, for an address or a poem, end the line with a backslash, which is visible and survives editors that trim trailing whitespace, or with two spaces, which works everywhere but is invisible. Some environments, GitHub comments and issues among them, treat every newline as a break; README files on GitHub do not. Our Markdown editor has a "Line breaks" switch to preview either behaviour.

Lists

- Bullets use -, * or +
- Keep one marker per list

1. Numbered lists use a number and a period
2. The numbers you type barely matter:
3. a list starting at 1 renders 1, 2, 3 even if every item says 1.

- Nesting: indent the child to line up
  with the parent's text (two spaces here)
  - like this
    1. and this

- [x] Task lists (GFM)
- [ ] render as checkboxes

The rule behind nesting is that a child item must be indented at least as far as the text of its parent, not its marker. For - item that is two spaces; for 1. item it is three. Four spaces always works, which is why many style guides recommend it. A paragraph or code block inside a list item needs the same indentation, plus a blank line before it.

[inline link](https://example.com "optional title")
<https://example.com>                          autolink, works everywhere
https://example.com                            bare URL, linked by GFM

[reference link][docs]
[docs]: https://example.com/docs

![alt text describing the image](diagram.png)
[![image that links](badge.svg)](https://example.com)

[Jump to a heading](#getting-started)

Heading anchors are generated by the renderer, not by Markdown itself. GitHub's rule, which most tools copy, lower-cases the text, removes punctuation and replaces spaces with hyphens, so ## Getting Started! becomes #getting-started; a repeated heading gets -1, -2 and so on. Always write useful alt text for images: it is what screen readers announce and what appears when the image fails to load.

Code blocks

```js
const answer = 42;
```

~~~python
print("tildes work too")
~~~

    four-space indented code also works,
    but has no language tag, so no highlighting

Put the language name directly after the opening fence for syntax highlighting: js, ts, python, bash, json, yaml, sql, diff and many more are recognised by GitHub, GitLab and most documentation generators. To show a fence inside a code block, open the outer block with four backticks.

Tables (GFM)

| Endpoint      | Method | Auth   |
| :------------ | :----: | -----: |
| /orders       | GET    | token  |
| /orders/{id}  | DELETE | admin  |

The second line is required: it separates the header and sets alignment with colons, left (:---), centre (:---:) or right (---:). The pipes do not need to line up in the source. A literal pipe inside a cell must be escaped as \|, cells cannot contain block content such as lists or multiple paragraphs, and a line break inside a cell needs an HTML <br>. For anything more complex, an HTML table or a link to a spreadsheet is clearer.

Escaping and raw HTML

A backslash before any ASCII punctuation character makes it literal: \*not italic\*, \# not a heading, 1\. not a list. Inside inline code and code blocks nothing needs escaping. Most renderers also accept raw HTML, such as <details> for collapsible sections, <kbd> for keys and <sup> for superscripts. GitHub and most hosted platforms sanitize it, removing scripts, event handlers and styles. If you render user-written Markdown in your own application, sanitize the generated HTML with a library such as DOMPurify; escaping the input is not enough, because Markdown syntax itself produces HTML. Our guide to HTML escaping and XSS contexts explains why.

GitHub-only extras

Some popular features are specific to GitHub and will appear as plain text elsewhere: @username mentions and #123 issue references; footnotes written as [^1]; alerts written as > [!NOTE], > [!WARNING] and similar; emoji shortcodes such as :rocket:; and Mermaid diagrams in a ```mermaid fence. They are worth using in a repository, but avoid them in documentation that will also be rendered by another tool.

Try any snippet with a live preview GitHub-flavored Markdown with a sanitized live preview, formatting toolbar, heading anchors, table of contents, and HTML export, all in your browser.
Open the Markdown editor

Frequently asked questions

End the line with a backslash, or with two trailing spaces, and continue on the next line. A plain newline inside a paragraph is treated as a space, and a blank line starts a new paragraph. The backslash is the more robust choice because it is visible in the source and is not removed by editors that strip trailing whitespace. Some platforms, such as GitHub comments, treat every newline as a break automatically.

Write a header row with cells separated by pipes, then a divider row of dashes, then one row per line: | Name | Role | on the first line, | --- | --- | on the second, and | Ada | Engineer | below. Add colons to the divider to align columns: :--- left, :---: centre, ---: right. Tables are a GitHub-Flavored Markdown extension, supported by GitHub, GitLab and most modern renderers.

A child list item must be indented at least as far as the text of its parent item, not just its marker. For a parent written as "- item" that means two spaces; for "1. item" it means three. Using four spaces for each level works in every renderer. Also make sure there is no blank line between items unless you want a loose list with paragraph spacing.

GitHub-Flavored Markdown is a superset of CommonMark, the standardised form of Markdown. It adds tables, task lists, strikethrough with double tildes, automatic linking of bare URLs, and rules for filtering unsafe raw HTML. GitHub itself adds further features on top, such as mentions, issue references, footnotes, alerts and Mermaid diagrams, that are not part of the GFM specification.

Put a backslash in front of it. \* shows a literal asterisk, \_ an underscore, \# a hash at the start of a line, \| a pipe inside a table cell and \` a backtick. Any ASCII punctuation character can be escaped this way. Inside inline code or a fenced code block, everything is already literal and needs no escaping.