GitHub Flavored Markdown (GFM) Explained
What GitHub Flavored Markdown adds on top of standard Markdown: tables, task lists, autolinks, strikethrough, emoji, and platform-specific features. With examples you can use today.
"Markdown" is not one thing. There's CommonMark (the formal specification), and there's everything people informally call "Markdown" — which in 2026 almost always means GitHub Flavored Markdown (GFM).
If you write README files, issue comments, or documentation, you're writing GFM whether you know it or not. This post covers every GFM extension: what it does, how to write it, and where it does and doesn't work.
What GFM adds on top of CommonMark
GFM is a strict superset of CommonMark. Any valid CommonMark document renders identically in GFM. GFM adds:
- Tables
- Task lists
- Strikethrough
- Autolinks
- Disallowed raw HTML (security)
- Better handling of multi-line list items
Plus GitHub.com adds some platform-specific rendering (emoji shortcodes, @mentions, issue linking, Mermaid diagrams) that isn't strictly in the GFM spec but travels with it.
Let's go through each.
1. Tables
Pipe-separated tables with an alignment row:
| Name | Role | Score | | :------ | :-----: | ----: | | Alice | Admin | 100 | | Bob | Editor | 85 | | Charlie | Viewer | 42 |
Renders as:
| Name | Role | Score |
|---|---|---|
| Alice | Admin | 100 |
| Bob | Editor | 85 |
| Charlie | Viewer | 42 |
Alignment is set by the colons in the second row:
:---→ left:---:→ center---:→ right---→ default (usually left)
Tips:
- You don't need to align the pipes visually — most editors do it for you.
- Don't try to nest tables. Markdown doesn't support it. Use HTML if you absolutely must.
- Tables can contain inline Markdown: links, bold, code, images.
- Tables cannot contain: block-level elements (paragraphs, lists, code blocks). Keep it simple.
If manually typing tables is painful, use our Markdown Table Generator.
2. Task lists
Unordered list items with a checkbox:
- [x] Write the README - [ ] Add CI pipeline - [ ] Publish to npm
Renders with interactive-looking checkboxes. On GitHub.com issue comments, they become actually interactive — you can click to toggle.
Notes:
- A lowercase
xbetween brackets means checked.[X](uppercase) also works on GitHub but isn't spec. - You can't have an unchecked state with anything other than a space between the brackets:
[ ]. - Task lists can be nested.
- Great for README roadmaps, PR descriptions ("Acceptance criteria"), and issue templates.
3. Strikethrough
~~This text is struck through.~~
Renders as: This text is struck through.
One tilde (~text~) does not work in GFM — you need two. This distinguishes GFM from some other Markdown dialects where single-tilde is valid.
4. Autolinks
Naked URLs become clickable links:
Visit https://mdkit.io for free tools. Contact us at contact@mdkit.io.
CommonMark requires you to wrap URLs in angle brackets: <https://example.com>. GFM auto-detects bare URLs and email addresses.
This is extremely convenient in issue comments and quick notes.
5. Disallowed raw HTML
GFM sanitizes certain HTML tags that would be security risks:
<script><style>(in some contexts)<iframe>(restricted)- Event handlers like
onclick=
Other tags pass through. This is why you can safely render user-submitted Markdown in a GFM renderer without worrying about XSS (mostly — always use a sanitizer in production).
6. Multi-line list items
CommonMark requires explicit 4-space indentation to continue a list item across lines. GFM is more forgiving:
- First item continues on this line without 4-space indent - Second item
In CommonMark, the second line would become a new paragraph. In GFM, it stays part of the same list item.
GitHub.com-specific extras
These aren't strictly GFM, but they work when your Markdown is rendered on GitHub.
Emoji shortcodes
:rocket: :heart: :sparkles: :+1:
Renders as: 🚀 ❤️ ✨ 👍
Full list: github.com/ikatyang/emoji-cheat-sheet.
Works on: GitHub.com, GitLab, Mattermost, some chat apps.
Does not work on: raw CommonMark renderers (unless you add an emoji plugin like remark-emoji).
@mentions
@octocat please review this PR.
Links to user profiles on GitHub. Behavior varies elsewhere.
Issue and PR references
Fixes #42. See also user/repo#101.
Auto-linked to the issue or PR on GitHub.
Commit SHAs
See a5c3785 for the fix.
GitHub auto-links 7–40 character hex strings to commits.
Mermaid diagrams
```mermaid graph LR A[Idea] --> B[PRD] B --> C[Design] C --> D[Ship] ```
GitHub renders Mermaid blocks as actual diagrams. So do GitLab, Obsidian, and Notion. Plain CommonMark shows them as code blocks.
Math
Inline math: $E = mc^2$ Block math: $$ \sum_{i=1}^{n} i = \frac{n(n+1)}{2} $$
GitHub uses KaTeX. Obsidian, Notion, and most static site generators with a math plugin support this too.
GitHub-specific alerts
GitHub introduced alert blocks in 2024, now part of GFM rendering:
> [!NOTE] > Highlights information users should know. > [!TIP] > Optional, but helpful advice. > [!IMPORTANT] > Crucial information. > [!WARNING] > Urgent; needs attention. > [!CAUTION] > Negative consequences of an action.
Works on GitHub.com. Not universally supported elsewhere (yet).
Where GFM renders correctly
| Platform | GFM support |
|---|---|
| GitHub.com | ✅ Full (reference renderer) |
| GitLab | ✅ Near-full |
| Bitbucket | ✅ Most features |
| VS Code preview | ✅ With default extensions |
| Obsidian | ✅ Near-full |
| Notion | ⚠️ Partial (no autolinks) |
| Typora | ✅ Full |
| npmjs.com (README) | ✅ Most features |
| PyPI (README) | ⚠️ Needs GFM content type |
| Discord | ⚠️ Subset (no tables) |
| Slack | ⚠️ Subset (no tables, no task lists) |
| ⚠️ Subset | |
| Static site generators | ✅ With remark-gfm plugin |
If you're targeting maximum compatibility, stick to CommonMark core. If you're targeting GitHub and modern tools, GFM is safe.
How to enable GFM in your toolchain
Marked (JavaScript)
import { marked } from "marked"; marked.use({ gfm: true, breaks: false }); const html = marked.parse(markdownText);
remark / rehype (unified ecosystem)
npm install remark remark-gfm remark-rehype rehype-stringify
import { unified } from "unified"; import remarkParse from "remark-parse"; import remarkGfm from "remark-gfm"; import remarkRehype from "remark-rehype"; import rehypeStringify from "rehype-stringify"; const html = await unified() .use(remarkParse) .use(remarkGfm) .use(remarkRehype) .use(rehypeStringify) .process(markdownText);
Markdown-it (JavaScript)
import MarkdownIt from "markdown-it"; const md = new MarkdownIt({ html: true, linkify: true }); // Tables, autolinks, etc. are on by default. // Task lists need markdown-it-task-lists plugin.
Pandoc
pandoc input.md -o output.html --from=gfm
Python (mistune, markdown-it-py)
from markdown_it import MarkdownIt md = MarkdownIt("gfm-like").enable("table").enable("strikethrough") html = md.render(markdown_text)
Practical gotchas
Autolinks in code
Check the URL: `https://example.com`
Inside backticks, autolinking is disabled (as it should be). Don't try to put links inside code spans.
Tables and line wrapping
Long table cells force wide horizontal scrolling on mobile. Consider splitting into multiple tables or using a definition list (HTML) for complex data.
Task list persistence
GitHub persists task list state when you edit the Markdown — but only in issues, PRs, and comments. In README files, toggling a checkbox doesn't save automatically (it opens the editor).
Nested lists in tables
| Feature | Notes | | :------ | :-------------- | | Auth | - OAuth<br>- JWT |
Lists inside table cells don't work in GFM. The workaround is <br> tags for line breaks, or structuring your content differently (use an H3 plus a list under the table).
Blockquote + list interaction
> Here's a quote: > - item one > - item two
Works. But forget the leading > on a continuation line and the rendering falls apart. Be consistent.
Summary
- GFM = CommonMark + tables, task lists, strikethrough, autolinks, better list handling.
- Enabled by default in most modern Markdown tools targeting technical content.
- Add
remark-gfm(or equivalent) to any static site generator that doesn't enable it by default. - Stick to GFM core for maximum portability; reserve GitHub-specific features (emoji, @mentions, alerts) for content that will only be rendered on GitHub.
You now know exactly what GFM adds and where it works. For a full syntax refresher, see our Markdown Cheat Sheet. For tables specifically, read Markdown Tables: syntax, alignment, and generators.
Frequently Asked Questions
Is GFM a separate language from Markdown?+
Where is GFM supported outside GitHub?+
What's the difference between GFM and CommonMark?+
Can I use GFM in a README on npm or PyPI?+
Are GitHub emoji shortcodes part of GFM?+
Keep reading
The Complete Markdown Cheat Sheet (2026)
Every Markdown syntax you'll ever need, in one reference: headings, lists, tables, code blocks, links, images, task lists, and GitHub extensions. Print-friendly and bookmark-ready.
Markdown Tables: Syntax, Alignment, and Generators
A complete guide to Markdown tables: GFM syntax, column alignment, escaping pipes, nested content, and when to reach for HTML instead. With copy-paste examples.
How to Write a Great GitHub README (With Template)
A complete guide to writing a README that gets stars, attracts contributors, and onboards users in seconds. Structure, tone, badges, screenshots, and a copy-paste template.