Markdown Syntax Guide: Complete Reference With Examples
Key Takeaways
- • Markdown is used by GitHub for all 420+ million repositories' READMEs — it's the de facto documentation format for developers.
- • Per the 2025 Stack Overflow Developer Survey, Markdown is the most admired documentation tool for the third consecutive year.
- • CommonMark (2014) standardized ambiguous original Markdown — use CommonMark-compatible syntax for maximum cross-platform portability.
- • GitHub Flavored Markdown (GFM) adds tables, task lists, strikethrough, and syntax-highlighted code blocks on top of CommonMark.
- • Most Markdown processors support inline HTML for features the spec doesn't cover (centering, image sizing, subscript).
Why Every Developer Needs to Know Markdown
In 2004, John Gruber published Markdown with a simple premise: "a text-to-HTML conversion tool for web writers." He could not have anticipated that twenty-two years later, Markdown would be the primary documentation format for GitHub's 420+ million repositories, the default in Notion, Obsidian, Linear, Jira, Confluence, Reddit, Discord, Slack, and virtually every modern developer tool.
The 2025 Stack Overflow Developer Survey, which collected over 49,000 responses from 177 countries, named Markdown the most admired documentation and synchronization tool for the third consecutive year — outranking every alternative including AsciiDoc and reStructuredText. It is not going away.
This guide covers the complete syntax: the core spec (CommonMark), the GitHub Flavored Markdown extensions (GFM), and the platform-specific quirks that catch developers off guard. Each section shows the raw Markdown source side-by-side with what it renders.
Convert between Markdown and HTML instantly with our HTML to Markdown converter.
The Markdown Specification Landscape
Original Markdown (2004) was intentionally underspecified — Gruber described the behavior for common cases but left edge cases to implementation discretion. This caused a fractured ecosystem where the same Markdown rendered differently across GitHub, Pandoc, and Jekyll.
| Spec | Year | Used By | Key Additions |
|---|---|---|---|
| Original Markdown | 2004 | Legacy sites | Core syntax (Gruber) |
| CommonMark | 2014 | Reddit, Discourse, Pandoc | Strict unambiguous spec |
| GFM | 2017 | GitHub, GitLab | Tables, task lists, strikethrough, autolinks |
| MDX | 2018 | Next.js docs, Storybook | JSX components in Markdown |
| Pandoc Markdown | 2006+ | Academic, technical writing | Footnotes, citations, math, definition lists |
Recommendation: Write to CommonMark for maximum portability. Use GFM extensions (tables, task lists) freely — they are supported in all major developer tools. Avoid Pandoc-specific extensions unless you are specifically targeting academic output.
Headings
Markdown supports two heading styles: ATX (using #) and Setext (using underlines). ATX is universal; Setext only supports H1 and H2. Use ATX.
Markdown source
# H1 — Page title (one per page)
## H2 — Major section
### H3 — Subsection
#### H4 — Sub-subsection
##### H5 — Rarely used
###### H6 — Rarely used
# ATX requires a space after #
## Alternative: Setext style (H1 and H2 only)
Heading 1
=========
Heading 2
---------Notes
• Always add a blank line before and after headings
• Use only one H1 per document (SEO + accessibility)
• Do not skip heading levels (H1 → H3 is an accessibility violation)
• GitHub automatically generates anchor IDs from heading text
• Link to a heading: [text](#heading-id)
Text Formatting
| Effect | Markdown Syntax | Alt Syntax | HTML Output |
|---|---|---|---|
| Bold | **bold** | __bold__ | <strong>bold</strong> |
| Italic | *italic* | _italic_ | <em>italic</em> |
| Bold italic | ***bold italic*** | ___bold italic___ | <strong><em>...</em></strong> |
| ~~strike~~ | GFM only | <del>strike</del> | |
Inline code | `code` | ``code`` | <code>code</code> |
| Highlight | ==highlight== | Pandoc/Obsidian | <mark>highlight</mark> |
| Subscript / Superscript | ~sub~ / ^super^ | Pandoc only | <sub> / <sup> |
Gotcha: Underscores inside words are not treated as emphasis markers in CommonMark: some_var_name renders literally. Use *asterisks* for emphasis to avoid this ambiguity.
Lists
<!-- Unordered list — use -, *, or + (be consistent) -->
- First item
- Second item
- Nested item (indent 2 spaces)
- Another nested item
- Third item
<!-- Ordered list — use numbers + period -->
1. First item
2. Second item
1. Nested ordered item
2. Another nested
3. Third item
<!-- Loose list (blank line between items = paragraph wrapper) -->
- This item gets wrapped in <p> tags
- This item too — blank line triggers loose mode
<!-- Task list (GFM extension) -->
- [x] Completed task
- [ ] Pending task
- [x] Another done taskCommonMark detail: In ordered lists, the actual numbers do not matter — CommonMark only uses the first number to determine the list start value. 1. 1. 1. renders as 1, 2, 3. The HTML start attribute is set to your first number if it isn't 1.
Loose vs tight lists: If any list item is separated by a blank line, the entire list becomes "loose" — every item gets wrapped in <p> tags. This affects spacing in rendered output. For compact lists, do not add blank lines between items.
Links and Images
<!-- Inline link -->
[Link text](https://bytepane.com)
<!-- Link with title (shown on hover) -->
[BytePane Tools](https://bytepane.com "Developer Tools")
<!-- Reference link (define URL separately) -->
[Link text][ref-id]
[ref-id]: https://bytepane.com "Optional title"
<!-- Auto-link (GFM) — URL becomes clickable automatically -->
https://bytepane.com
<!-- Bare email auto-link -->
<[email protected]>
<!-- Link to heading anchor (GitHub generates IDs from heading text) -->
[Jump to section](#heading-text-lowercased-with-hyphens)
<!-- Image syntax (like link but with ! prefix) -->


<!-- Image with link (nest inside link) -->
[](https://bytepane.com)
<!-- Image sizing requires inline HTML -->
<img src="image.png" width="300" alt="Description">Accessibility: Alt text is not optional. Screen readers announce image alt text to visually impaired users. For decorative images, use an empty alt (). For informational images, describe the content — not the visual style.
Reference-style links are useful when the same URL appears multiple times, or when long URLs would break the reading flow of the source. The reference definitions can go anywhere in the document — most people put them at the bottom.
Code: Inline and Blocks
<!-- Inline code: single backticks -->
Use the `console.log()` function to debug.
<!-- If code contains backticks, use double backticks as delimiter -->
`` const x = `template` ``
<!-- Fenced code block with language identifier -->
```javascript
const greet = (name) => `Hello, ${name}!`
console.log(greet('World'))
```
<!-- Common language identifiers -->
```python → Python
```bash → Shell/bash scripts
```sql → SQL queries
```json → JSON
```yaml → YAML
```tsx → TypeScript + JSX
```go → Go
```rust → Rust
```diff → Diff output (shows +/- coloring)
<!-- Indented code block (4 spaces — original Markdown, CommonMark) -->
This is a code block
via indentation (no language highlighting)
<!-- Line numbers: not in spec, depends on renderer -->
```javascript showLineNumbers
// Some renderers (MDX, Prism) support showLineNumbers
```Performance tip: Syntax highlighting libraries like Prism.js and highlight.js add significant bundle weight. For static sites, use a build-time highlighter like shiki (which ships zero JavaScript to the client) rather than client-side highlighting. Shiki uses VS Code's TextMate grammars — the same quality as your editor.
Tables (GFM Extension)
<!-- Basic table (GFM) -->
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Cell 1 | Cell 2 | Cell 3 |
| Cell 4 | Cell 5 | Cell 6 |
<!-- Alignment: colons in separator row -->
| Left | Center | Right |
|:---------|:--------:|---------:|
| aligned | centered | aligned |
| left | middle | right |
<!-- Pipe chars in cells: escape with \ -->
| Header | Value |
|-----------|-------------|
| Pipe char | \| escaped |
<!-- Pipes at line edges are optional in CommonMark -->
Column A | Column B
---------|----------
Value A | Value B| Table Feature | CommonMark | GFM | Pandoc |
|---|---|---|---|
| Pipe tables (basic) | No | Yes | Yes |
| Column alignment | No | Yes | Yes |
| Multi-line cells | No | No | Yes (grid tables) |
| Colspan/rowspan | No | No | No |
Gotcha: Tables require a header row and a separator row — you cannot have a headerless table in GFM. For complex tables needing colspan/rowspan, fall back to inline HTML <table>.
Blockquotes
<!-- Basic blockquote -->
> This is a blockquote.
> It can span multiple lines.
<!-- Nested blockquote -->
> Level 1 quote
>> Level 2 (nested)
>>> Level 3
<!-- Blockquote with other Markdown inside -->
> ## Heading inside blockquote
>
> - List item
> - Another item
>
> ```javascript
> console.log('code in quote')
> ```
<!-- GitHub callouts (GFM extension, supported since 2023) -->
> [!NOTE]
> Useful information for readers.
> [!WARNING]
> Critical information — important warnings.
> [!TIP]
> Helpful but optional suggestions.
> [!IMPORTANT]
> Key information readers must not miss.
> [!CAUTION]
> Advises about risks or negative consequences.GitHub's callout syntax (> [!NOTE]) was introduced in September 2023 and renders with colored icons in GitHub. Other platforms may render it as a plain blockquote — test in your target environment.
Horizontal Rules and Line Breaks
<!-- Horizontal rule — three or more of: ---, ***, or ___ -->
---
***
___
<!-- All produce: <hr /> -->
<!-- Line break within a paragraph — two methods: -->
Method 1: two trailing spaces (may be stripped by editors)
Next line
Method 2: backslash at end of line (CommonMark)\
Next line
<!-- Hard vs soft wraps:
A single newline = soft wrap = same paragraph
A blank line = new paragraph
Trailing spaces or \ = <br> tag -->
Paragraph one text here.
Still the same paragraph (soft wrap).
New paragraph starts here (blank line above).Editor warning: Many editors (VS Code, vim with set expandtab, prettier) automatically strip trailing whitespace, silently breaking the two-space line break. The backslash method is safer for this reason, though it was only standardized in CommonMark — not the original Markdown spec.
Footnotes and Definition Lists
<!-- Footnotes (Pandoc, GitHub, some renderers) -->
Here is a sentence with a footnote.[^1]
Another sentence with a longer note.[^longnote]
[^1]: Short footnote text.
[^longnote]: Longer footnote. Can contain
multiple paragraphs if indented.
<!-- Definition lists (Pandoc extension) -->
Term 1
: Definition 1
Term 2
: Definition 2a
: Definition 2b
<!-- Abbreviations (PHP Markdown Extra) -->
*[HTML]: HyperText Markup Language
*[CSS]: Cascading Style Sheets
The HTML and CSS are used together.
<!-- "HTML" and "CSS" get <abbr> titles in output -->Platform support: Footnotes are supported on GitHub (as of 2022), Pandoc, and Obsidian. They are not part of CommonMark or GFM core — check your renderer's documentation. Definition lists and abbreviations are Pandoc/PHP Markdown Extra extensions — avoid for maximum portability.
Escaping Characters and Inline HTML
<!-- Escape formatting characters with backslash -->
\ ` * _ { } [ ] ( ) # + - . ! |
\*Not emphasized\* → *Not emphasized*
\_Not italic\_ → _Not italic_
\[Not a link\] → [Not a link]
<!-- Inline HTML (passed through by most processors) -->
<div align="center">
Centered content here.
</div>
<!-- Useful inline HTML for features Markdown lacks -->
<details>
<summary>Click to expand</summary>
Hidden content revealed on click. Supported by GitHub!
</details>
<!-- Subscript and superscript -->
H<sub>2</sub>O → H₂O
x<sup>2</sup> → x²
<!-- Keyboard shortcut rendering -->
Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to copy.
<!-- Colored text (inline HTML — some renderers strip this) -->
<span style="color: red">Red text</span>Security note: When rendering user-supplied Markdown, always sanitize HTML. Many renderers (marked.js, remark) have a sanitization option — enable it. Alternatively, use DOMPurify after rendering to strip dangerous tags (<script>, event attributes). GitHub sanitizes Markdown from untrusted sources at render time.
Front Matter and MDX
<!-- YAML front matter (Jekyll, Hugo, Astro, Next.js MDX) -->
---
title: "Markdown Syntax Guide"
date: 2026-04-26
author: BytePane Team
tags: [markdown, documentation, reference]
draft: false
---
# Article content starts here
<!-- MDX: Markdown + JSX components (Next.js, Docusaurus) -->
import { Button } from '@/components/Button'
import DataTable from './DataTable'
## Using React components in Markdown
<Button href="/regex-tester/" variant="primary">
Open Regex Tester
</Button>
<DataTable data={stats} />
Normal Markdown content continues here.MDX (Markdown + JSX) is the standard format for Next.js documentation sites and Docusaurus. It compiles to JavaScript, which means full React component support — interactive examples, data visualizations, and live code playgrounds inside Markdown. The trade-off is that MDX requires a build step and is not portable to non-React environments.
Complete Syntax Quick Reference
| Element | Syntax | Spec |
|---|---|---|
| Heading 1 | # H1 | Core |
| Heading 2–6 | ## H2 through ###### H6 | Core |
| Bold | **text** or __text__ | Core |
| Italic | *text* or _text_ | Core |
| Bold + italic | ***text*** | Core |
| Strikethrough | ~~text~~ | GFM |
| Inline code | `code` | Core |
| Code block | ```lang\ncode\n``` | CommonMark |
| Blockquote | > text | Core |
| Unordered list | - item or * item | Core |
| Ordered list | 1. item | Core |
| Task list | - [x] done / - [ ] todo | GFM |
| Horizontal rule | --- or *** or ___ | Core |
| Link | [text](url) | Core |
| Reference link | [text][id] [id]: url | Core |
| Image |  | Core |
| Auto-link | <url> or bare URL | GFM |
| Table | | col | col |\n|---|---| | GFM |
| Footnote | text[^1] [^1]: note | Pandoc/GitHub |
| HTML | <tag>content</tag> | Core |
| Escape | \* \_ \[ etc. | Core |
| Hard line break | line \n (2 spaces) | Core |
| Hard break alt | line\\\n (backslash) | CommonMark |
| GitHub callout | > [!NOTE] | GFM (2023) |
| Front matter | ---\nyaml\n--- | Jekyll/SSG |
Platform-Specific Quirks
Markdown rendering varies across platforms even when they claim CommonMark compliance. Here are the most common real-world differences:
| Platform | Parser | Key Quirks |
|---|---|---|
| GitHub (Issues/PRs) | cmark-gfm | Full GFM; sanitizes HTML; @mentions; #issue links auto-link |
| GitHub (README) | cmark-gfm | Same as above; some HTML allowed (align, width on img) |
| GitLab | commonmarker | GFM-like; footnotes supported; more permissive HTML |
| Slack | Custom | No tables; *bold* = single asterisk; different escaping |
| Discord | Custom | No tables or images; underline via __text__ differs |
| Notion | Custom | Imports GFM; exports with Notion extensions |
| Custom | New Reddit: CommonMark. Old Reddit: custom parser (different rules) |
Frequently Asked Questions
What is the difference between Markdown and HTML?
Markdown is an authoring format that compiles to HTML. Where HTML uses <strong>bold</strong>, Markdown uses **bold**. Markdown is faster to write and more readable as plain text. Most Markdown parsers support inline HTML for features Markdown lacks (image sizing, centered text). Markdown is not a replacement for HTML — it is a faster way to produce it.
What is GitHub Flavored Markdown (GFM)?
GFM is a CommonMark superset that adds tables, task lists, strikethrough, autolinks, and fenced code blocks with syntax highlighting. Formally specified at github.github.com/gfm/ in 2017, it is now the standard on GitHub, GitLab, and most developer tools. Use GFM features freely — they are well-supported.
How do I create a line break in Markdown?
Two methods: (1) Two trailing spaces followed by a newline — but many editors strip trailing spaces silently. (2) A backslash \ at the end of the line — supported in CommonMark but not original Markdown. A blank line creates a new paragraph. The backslash method is safer for cross-editor compatibility.
How do I add syntax highlighting to code blocks?
Use fenced code blocks with a language identifier: ```javascript. Renderers use the hint for highlighting via Prism.js, highlight.js, or shiki. Common identifiers: javascript, python, bash, sql, json, yaml, typescript, go, rust, diff. If no language is specified, most renderers show unhighlighted monospace text.
Can I use HTML inside Markdown?
Yes — most Markdown processors pass raw HTML through to the output. Useful for features Markdown lacks: <details>/<summary> (collapsible sections on GitHub), <img width="200"> (image sizing), <sub>, <sup> (subscript/superscript). Sanitized environments (GitHub comments) strip some HTML tags for security.
What is the difference between CommonMark and original Markdown?
Original Markdown (2004) left edge cases underspecified, causing different parsers to behave differently. CommonMark (2014) is a complete, unambiguous specification that standardizes all edge cases. Most modern renderers use CommonMark or a superset (GFM). Write to CommonMark syntax for maximum portability.
How do I escape Markdown formatting characters?
Use a backslash: \* renders as *, \_ as _, \[ as [. Escapable: \ ` * _ { } [ ] ( ) # + - . ! |. Inside a code span or fenced block, all characters render literally — no escaping needed. This is the simplest way to display characters that would otherwise trigger formatting.
Convert HTML to Markdown Instantly
Paste any HTML and get clean, portable Markdown back — useful for migrating docs, pasting web content, or converting rich text from CMS editors.
Open HTML to Markdown Converter →