Markdown Guide: Syntax Reference and Best Practices
April 6, 2026 · 7 min read
Markdown is a lightweight markup language that converts plain text to HTML. Created by John Gruber in 2004, it is now the default documentation format for README files, wikis, blog posts, and technical writing. This guide covers all the syntax you need, including GitHub Flavored Markdown (GFM) extensions.
Headings
# H1 — Page title ## H2 — Major section ### H3 — Subsection #### H4 — Minor heading <!-- Alternative syntax for H1 and H2 --> Page Title ========== Major Section -------------
Text Formatting
**bold text** or __bold text__ *italic text* or _italic text_ ***bold and italic*** ~~strikethrough~~ (GFM) `inline code` > blockquote >> nested blockquote
Lists
Unordered lists
- Item one - Item two - Nested item (2 spaces of indentation) - Another nested item - Item three * Also works with asterisks + And with plus signs
Ordered lists
1. First item 2. Second item 3. Third item <!-- The actual numbers don't matter — they render sequentially --> 1. First 1. Second 1. Third
Task lists (GFM)
- [x] Write the draft - [x] Add code examples - [ ] Peer review - [ ] Publish
Links and Images
[Link text](https://example.com) [Link with title](https://example.com "Hover tooltip") <!-- Reference-style links --> [io9.me][io9] [io9]: https://io9.me "Developer Tools" <!-- Images -->  ![Alt text][img-ref] [img-ref]: https://example.com/image.png <!-- Bare URLs and emails are auto-linked in GFM --> https://example.com contact@example.com
Code
Inline code
Use `backticks` for inline code: `const x = 1;`
Fenced code blocks
```javascript
function greet(name) {
return `Hello, ${name}!`;
}
```
```python
def greet(name):
return f"Hello, {name}!"
```
<!-- Supported language identifiers: js, ts, python, bash, sql, json, yaml, css, html, rust, go, java, c, cpp, ... -->Tables (GFM)
| Column 1 | Column 2 | Column 3 | |----------|----------|----------| | Cell | Cell | Cell | | Cell | Cell | Cell | <!-- Alignment --> | Left | Center | Right | |:---------|:--------:|---------:| | aligned | aligned | aligned |
Horizontal Rules
--- *** ___ <!-- Three or more dashes, asterisks, or underscores -->
HTML in Markdown
Most Markdown processors allow raw HTML. This is useful for features Markdown does not support natively, like coloured text, collapsible sections, or complex tables.
<details> <summary>Click to expand</summary> Hidden content here. **Markdown still works inside.** </details> <kbd>Ctrl</kbd>+<kbd>C</kbd> <!-- keyboard key styling -->
Escaping Special Characters
* ` _ # [ ] ( ) { } . !
<!-- Backslash escapes prevent Markdown from interpreting these characters -->CommonMark vs GFM vs Others
| Feature | CommonMark | GFM (GitHub) |
|---|---|---|
| Tables | ✗ | ✓ |
| Task lists | ✗ | ✓ |
| Strikethrough | ✗ | ✓ |
| Autolinks | Basic | Extended |
| Fenced code blocks | ✓ | ✓ |
Best Practices
Use one blank line between paragraphs and block elements. Keep line lengths under 100 characters for readability in source editors. Use ATX-style headings (#) instead of Setext-style (underlines) for consistency. Add language identifiers to all code blocks so syntax highlighting works. Use reference-style links when a URL appears more than once.
The Text Tools on io9.me can help you escape special characters when embedding content in Markdown or HTML.