Markdown Syntax Cheat Sheet for READMEs and Docs
Markdown is the default dialect for README files, PR descriptions, and half the docs sites on the internet. The painful part is that “Markdown” is not one language — CommonMark, GitHub Flavored Markdown (GFM), and static-site flavors disagree on tables, autolinks, and HTML passthrough. This cheat sheet targets GFM as used on GitHub and GitLab, with notes where other renderers diverge.
Headings and structure
# H1 — use sparingly in READMEs (the repo title is already an H1 in the UI)
## H2 section
### H3 subsection
Leave a blank line before and after headings. Do not skip levels (## then ####) if you care about accessible outline navigation. Underline-style Setext headings (===) work but are rare in modern repos — prefer ATX # markers.
Emphasis, code, and escaping
| You type | You get |
|---|---|
*italic* or _italic_ | italic |
**bold** | bold |
`inline code` | inline code |
~~strike~~ | strike (GFM) |
\*literal asterisk\* | *literal asterisk* |
Nest backticks carefully: use double backticks to wrap a string that contains a single backtick. Escape Markdown punctuation with \ when a filename like file_name underscores italicize mid-word in some parsers — wrapping in backticks is usually cleaner.
Lists, tasks, and nesting
- Unordered item
- Nested item (two spaces or one tab — stay consistent)
1. Ordered item
2. Second item
- [ ] Open task
- [x] Done task
Tight vs loose lists (blank lines between items) change spacing. In GFM, task lists are real checkboxes in issues and PRs; in many static generators they are just Unicode.
Links, images, and references
[Visible text](https://example.com "optional title")

[ref-style]: https://example.com
See the [docs][ref-style].
Always write meaningful alt text for images in docs — “screenshot” fails accessibility and search. Relative links break when the same Markdown is rendered from different base paths (docs site vs raw GitHub); prefer paths from repo root or absolute docs URLs for critical links.
Fenced code and diff hints
```ts
export function greet(name: string) {
return `Hello, ${name}`;
}
```
```diff
- const legacy = true;
+ const legacy = false;
```
Declare a language tag whenever possible for highlighting. Indenting four spaces still creates code blocks in CommonMark, but fences are clearer for copy-paste. Nested fences (documenting Markdown itself) need extra backticks on the outer fence, as in the example above.
Tables without pain
| Field | Type | Notes |
|------:|------|-------|
| id | string | required |
| email | string | unique |
Alignment colons (:---, ---:, :---:) are optional. Wide tables are miserable on mobile — split them or use definition lists for long prose cells. Some renderers choke on pipes inside cells; escape as \| or wrap cell content in backticks.
Block quotes, HR, and HTML
> Tip: quote a single idea per block.
>
> Nested quotes work when you need callouts.
---
GFM allows a subset of raw HTML (<details>, <kbd>, etc.). Static site generators may sanitize differently — never paste untrusted HTML into docs that ship to a browser.
GitHub also supports alert blockquotes in some contexts:
> [!NOTE]
> Useful for reader callouts on GitHub.
Confirm support on your forge before relying on them in a README that must also build in MkDocs or Docusaurus.
Footnotes and footnotes-like patterns
GFM supports footnotes on GitHub:
Here is a claim.[^1]
[^1]: Source or aside that would clutter the paragraph.
Other engines use different footnote syntax or none at all. When portability matters, prefer a short parenthetical or a linked “Notes” section.
Copy-paste README skeleton
# Project name
One paragraph: what it does and who it is for.
## Install
## Usage
## Configuration
## Contributing
## License
Fill Usage with a minimal code fence that runs. Empty sections are worse than omitting the heading.
Frequent rendering bugs
| Symptom | Likely cause |
|---|---|
| List “eats” the next paragraph | Missing blank line after list |
| Table not rendering | Missing header separator row |
| Image 404 on GitHub | Wrong relative path from the Markdown file |
| Autolink weirdness | Angle brackets vs bare URLs |
Broken underscore in snake_case | Emphasis rules — wrap in backticks |
Bottom line
Learn one dialect well (GFM for forge READMEs), keep fences and tables boring, and write alt text and runnable examples. Markdown stays readable in source — that is the point — as long as you avoid relying on the one clever extension your local preview supports and GitHub does not.
Code documentation hygiene
Fenced code samples should compile or run when claimed. Pseudocode should be labeled. Outdated snippets erode trust faster than missing docs. Prefer linking to a maintained example file in the repo when samples are long.