This Markdown cheat sheet gives each piece of syntax next to the HTML it produces. The core comes from the CommonMark 0.31.2 specification. Tables, task lists, strikethrough, bare-URL autolinks and the raw-HTML filter come from GitHub Flavored Markdown (GFM 0.29), which GitHub, GitLab, many static site generators and the Markdown Preview on this site build on. Features that exist only on github.com, such as alerts, Mermaid diagrams and @mentions, have their own section, with the GitHub Docs page for each.

Every “renders as” value below was produced by running the input through micromark 4 with its GFM extension, the same parser and options the Markdown Preview uses, on 2026-10-02. Where GitHub’s own renderer gives a different result, the text says so; those results come from GitHub’s Markdown API (POST /markdown) on the same day.

Headings and Paragraphs

MarkdownRenders asNote
# Title … ###### Level 6<h1> … <h6>a space after the # run is required
#5 is not a heading<p>#5 is not a heading</p>no space, so it stays a paragraph
Setext + next line ======<h1>Setext</h1>setext heading; ------ gives <h2>
two lines with no blank lineone <p>the line break becomes a space
blank linenew <p>paragraphs are separated by blank lines

Line breaks trip people up more than anything else. A single newline inside a paragraph is a “soft line break”: CommonMark renders it as a newline in the HTML source, which a browser shows as a space. To force a <br />, end the line with two spaces or a backslash:

line one··
line two\
line three
line four

(·· stands for two spaces.) The first two lines end in a hard break; line three and line four join into one visual line. GitHub behaves differently depending on where you write. Its docs say that in issues, pull requests and discussions “GitHub will render a line break automatically”, while in a .md file the same text “would render on one line” (GitHub Docs: Line breaks). The Markdown API shows the same split: line one⏎line two comes back without <br> in markdown mode and with <br> in gfm mode, the mode used for comments. A README that looks right in an issue comment can therefore collapse into one paragraph once committed. Prefer the backslash: trailing spaces are invisible and many editors strip them on save.

Emphasis and Strikethrough

MarkdownRenders as
*italic* or _italic_<em>italic</em>
**bold** or __bold__<strong>bold</strong>
***both***<em><strong>both</strong></em>
~~deleted~~ (GFM)<del>deleted</del>
`code`<code>code</code>

Asterisks and underscores are not interchangeable inside a word. CommonMark lets * open and close emphasis in the middle of a word but not _, so snake_case_name and *a*b keeps the underscores and italicises only the a. That rule is what lets identifiers like snake_case_name survive in prose without backticks.

Strikethrough is not part of CommonMark: ~~two~~ ~one~ stays literal text there. The GFM spec allows one or two tildes, and both GitHub and the Markdown Preview strike through ~one~ as well as ~~two~~. Other renderers accept only two tildes, so write ~~ for portability.

Emphasis next to punctuation follows the “flanking” rules (CommonMark §6.2). A closing ** that comes right after punctuation must be followed by a space or punctuation. In English this rarely matters because words are separated by spaces. In Chinese, Japanese and Korean text it does: **注意:**ここは必須です renders as literal asterisks on GitHub and in the Markdown Preview, because : is punctuation and the next character is a letter.

Lists and Task Lists

MarkdownResult
3. three / 4. four<ol start="3">: the first number sets the start
1) one / 2) twoordered list; ) works as well as .
* one / - twotwo lists: changing the bullet character starts a new list
- a / - b / - cone flat list of three items
- a / - b / - cthree levels of nesting
- [ ] todo / - [x] doneGFM task list: disabled checkboxes

Only the first number of an ordered list matters; the rest are renumbered, so 1. on every line is a common way to avoid renumbering diffs (CommonMark §5.3). Nesting depends on where the content of the parent item starts, not on a fixed tab width. After - the content starts in column 3, so a child needs at least two spaces of indentation; one space is not enough. After 10. it starts in column 5, so a child of a two-digit item needs four.

Task lists are GFM; the Markdown Preview renders them as display-only (disabled) checkboxes. GitHub’s docs add one trap: if the item text starts with a parenthesis, escape it, as in - [ ] \(Optional) Open a followup issue (GitHub Docs: Task lists).

Code: Inline and Fenced

MarkdownRenders as
`x`<code>x</code>
`` `npm i` ``<code>npm i</code>: use more backticks than the code contains, with a space inside
```js … ```<pre><code class="language-js">
four backticks around a three-backtick blockshows the inner fence as text
4-space indentindented code block (no language)

To show a fenced block inside a fenced block, make the outer fence longer:

````markdown
```js
let a = 1;
```
````

The word after the opening fence is the “info string”. CommonMark only says that its first word is usually the language; the parser turns it into class="language-js" and leaves highlighting to the renderer. GitHub applies its own highlighter, and the Markdown Preview highlights a fixed set (JavaScript, TypeScript, Python, Go, PHP, Ruby, Java, Bash, JSON, XML/HTML, CSS, Markdown) with highlight.js. A block fenced with mermaid is rendered as a diagram on GitHub and as plain code everywhere else.

MarkdownRenders as
[link](https://example.com "title")<a href="…" title="title">
[Docs][MD] plus [md]: https://spec.commonmark.org/reference link; labels are case-insensitive
<https://example.com>autolink (CommonMark)
https://example.com and www.example.comboth linked in GFM; neither in plain CommonMark
[a](<my file.md>)a URL with a space needs angle brackets; becomes my%20file.md
![alt text](image.png "title")<img src="image.png" alt="alt text" title="title" />
[![alt](badge.svg)](https://example.com)linked image, the usual README badge

The www. form is a GFM extension and gets http://, not https://, so write the scheme yourself when it matters. The Markdown Preview opens links in a new tab and empties href values that use schemes other than http, https, mailto, irc, ircs and xmpp (micromark’s safe default), so [x](javascript:alert(1)) produces a link that goes nowhere.

Tables

| Plan  | Seats | Price |
|:------|:-----:|------:|
| Free  |   1   |    $0 |
| Team  |  10   |   $50 |
  • The second row is the delimiter row; it decides that this is a table. :--- is left, :---: centre, ---: right.
  • The pipes do not need to line up, and the leading and trailing pipes are optional.
  • Cells hold inline content only: emphasis, code, links. A list or a code block inside a cell is not possible; use <br> where raw HTML is allowed.
  • A literal pipe inside a cell, including inside backticks, must be written \|. The table | a | b | / |:-|-:| / | `x \| y` | **z** | renders the code span as x | y.

Tables are a GFM extension; plain CommonMark shows them as a paragraph of pipes. The Markdown Table Generator builds the delimiter row and escapes pipes for you, and imports CSV or JSON.

Blockquotes, Rules and Escapes

MarkdownRenders as
> quote / > / > > nested<blockquote> with a nested <blockquote>
---, ***, ___ on their own line<hr />
Text then --- on the next line<h2>Text</h2>, not a rule: add a blank line first
\*not italic\**not italic*

Any ASCII punctuation character can be escaped with a backslash (CommonMark §2.4); a backslash before a letter or a non-ASCII character stays a literal backslash. Escapes do not work inside code spans or code blocks, where everything is literal.

Raw HTML

The CommonMark spec passes raw HTML through, so <details>, <kbd>, <sup> and HTML comments are valid Markdown; whether they survive depends on the renderer. GFM adds a “tagfilter” that disables nine tags, including <script>, <style>, <iframe>, <textarea> and <title> (GFM §6.11). GitHub goes further and sanitizes attributes: sending <script>alert(1)</script> <b onclick="x()">b</b> to its API returns the script tag escaped as text and <b>b</b> without the onclick.

<details><summary>More</summary>

Hidden **text**

</details>

On GitHub this renders as a collapsible section with bold text inside; the blank lines around the Markdown are needed so it is parsed as Markdown, not as part of the HTML block. The Markdown Preview runs on zerotool.dev and escapes every HTML tag so that pasted text cannot run script on the page, which means <details> appears as text there. The Markdown inside it still renders. Check collapsible sections on GitHub itself.

GitHub-Only Syntax

These work on github.com but are not in CommonMark or the GFM spec. Elsewhere they show up as plain text.

SyntaxWhat it doesSource
Text[^1] and [^1]: Note.Footnote, collected at the bottomFootnotes
> [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION]Coloured alert boxAlerts
```mermaidDiagram (also geoJSON, topoJSON, ASCII STL)Creating diagrams
$\sqrt{2}$, $$…$$Math rendered with MathJaxMathematical expressions
:tada:Emoji from a shortcodeUsing emojis
@user, @org/teamMention and notificationMentioning people
#26, GH-26, owner/repo#26, a commit SHALinks to issues, PRs and commitsAutolinked references
> [!NOTE]
> Useful information.

GitHub’s docs add limits: alerts “cannot be nested within other elements”, footnotes “are not supported in wikis”. The Markdown Preview supports footnotes (micromark’s GFM extension includes them) and shows alerts as an ordinary blockquote starting with [!NOTE]; it has no emoji shortcodes, Mermaid or math.

Where Platforms Differ

InputCommonMarkGitHub (.md file)GitHub (gfm mode, comments)Markdown Preview
single newlinespacespace<br>space
~one~textstrikethroughstrikethroughstrikethrough
www.example.comtextlinklinklink
<details>HTMLHTMLHTMLescaped text
<b onclick="x()">HTML<b> without onclick<b> without onclickescaped text
**注意:**ここliteral **literal **literal **literal **

Notion is a block editor that converts some Markdown as you type: its help centre lists ** for bold, ~ for strikethrough, [] for a checkbox, and, unlike every Markdown renderer, > plus space for a toggle list and " plus space for a quote (Notion Help: Writing & editing basics). Typing a GitHub-style > quote in Notion therefore creates a toggle list, not a quote.

Checking Markdown Before You Commit

Three checks catch most problems. Paste the file into the Markdown Preview to see the rendering and copy the HTML. Run the Markdown Linter, which applies markdownlint 0.40 with its default rules. For this input:

# Release notes

See https://example.com for details.

### Fixed

* one
- two

it reports MD034 (bare URL) on line 3, MD001 (heading level jumps from 1 to 3) on line 5, MD004 (inconsistent bullet style) on line 8, and MD032 (lists should be surrounded by blank lines) on lines 7 and 8. The last one exposes the parser rule from the lists section: * one and - two are two separate lists. Finally, for anything GitHub-specific, such as alerts, Mermaid, math or a <details> block, check on github.com, because no general-purpose renderer reproduces those.