Markdown Preview Before PR — README Embarrassment Avoidance
You open the PR and the README table is a single mangled paragraph. A pipe inside a cell was not escaped. The install section’s nested list collapsed. A code block that should have been bash rendered as prose because the fence never closed. None of this failed CI. It failed the first human glance.
Markdown is forgiving to authors and picky to renderers. GitHub Flavored Markdown (GFM) is not identical to CommonMark-only tools, Notion paste, or Discord. Preview against the target that matters — for READMEs, that is GitHub.
Mistakes that show up only after push
Tables. Every row needs the same column count. Pipes inside cells need escaping (\|) or the row splits early. Alignment colons in the header separator are optional; broken separators are not.
Lists. A blank line before a list helps some parsers. Indent nested lists with four spaces or a tab consistently. Mixing * and - randomly is fine for GFM but looks sloppy.
Code fences. Closing ``` must be present. Language tags (```ts) improve highlighting. Tabs vs spaces inside the fence are preserved — do not “fix” Makefile tabs into spaces.
Links and images. Relative links behave differently from repo root vs from docs/. Test clicks on the rendered page, not only the raw file.
Preview in the GitHub UI, locally with a GFM-aware tool, or paste into a Markdown preview before the PR if you want a fast smoke check. The goal is catching render bugs without burning reviewer patience.
A README pass that takes five minutes
- Render headings — is there a single clear H1?
- Skim install commands in fenced blocks — copy-paste once yourself.
- Open every table on a narrow window — does it scroll or explode?
- Check badges — expired CI badges teach distrust.
- Confirm relative links from the default branch path.
| Flag | Meaning |
| --- | --- |
| `--dry-run` | Print actions only |
| `--path \| file` | Escape pipes in cells |
GFM features people assume are universal
| Feature | GitHub | Elsewhere |
|---|---|---|
| Tables | Yes | Often yes |
Task lists - [ ] | Yes | Mixed |
Strikethrough ~~ | Yes | Mixed |
| Footnotes | Limited / evolving | Mixed |
| Raw HTML | Partially sanitized | Varies |
Writing “GFM = all platforms” sets you up for Slack/Notion surprises. Prefer boring Markdown for README portability; use GFM extras when they clearly help GitHub readers.
Code blocks and secrets
READMEs sometimes paste .env examples. Use obvious placeholders (sk_live_... → sk_live_REDACTED). Formatters and previews will not warn you that you committed a real key.
Also avoid wrapping entire YAML manifests in indentation that turns them into nested list items — a common copy-paste footgun from editors that auto-indent.
FAQ
Should I commit rendered HTML?
No for READMEs. Commit Markdown; let GitHub render.
Why does my list merge with the previous paragraph?
Often missing a blank line before the list, or the previous line ends in a way that continues a paragraph.
Do tabs vs spaces in fences matter?
Yes for Makefiles and some configs. Preserve intentional tabs.
Preview, fix tables and lists, then push. The embarrassment is free to avoid and expensive once reviewers screenshot it.