← Blog

GitHub Flavored Markdown: what's different from CommonMark

GitHub Flavored Markdown (GFM) extends CommonMark with tables, task lists, autolinks, strikethrough, and a few other features. Every difference, in one page.

GitHub Flavored Markdown — GFM — is the dialect of Markdown that GitHub renders. It's also the de-facto standard for most of the modern Markdown web: GitLab, Gitea, Forgejo, Codeberg, Discord (mostly), Notion (partially), Reddit, Stack Overflow. If you write Markdown that needs to render correctly across the internet, target GFM.

This guide covers exactly what GFM adds to CommonMark, the rules that catch people, and which renderers support GFM.

What CommonMark is (the baseline)

CommonMark is the formal Markdown spec. It's strict, well-defined, and covers the core syntax:

  • Headings (# through######)
  • Paragraphs
  • Bold (**), italic (*), inline code (`)
  • Lists (ordered + unordered)
  • Block quotes (>)
  • Code blocks (fenced with backticks or indented 4 spaces)
  • Links ([text](url)) and images (![alt](url))
  • Horizontal rules (---)
  • HTML passthrough (raw HTML in Markdown is allowed, by default)

That's the entire CommonMark surface. Notice what's missing:tables,task lists,strikethrough,autolinks,emoji shortcodes. None of those are in CommonMark.

If you write| a | b | in pure CommonMark, the renderer shows literal pipe characters. If you writehttps://example.com on its own, it shows as plain text — not a clickable link. If you write~~strikethrough~~, you get literal tildes.

What GFM adds

GFM is CommonMark plus extensions. The full list:

Tables

| Header 1 | Header 2 | Right |
| -------- | :------: | ----: |
| Cell     | Centered |    99 |

GFM tables. The first row is the header. The delimiter row defines alignment via colons (:-- left,:-: center,--: right). Body rows match the column count.

Tables are the GFM feature most likely to break in production. AI assistants produce tables with mismatched column counts that GFM renderers handle differently (some pad, some truncate, some refuse). SeeHow to repair broken Markdown tables for the fastest fix.

Task lists

- [ ] Unchecked task
- [x] Completed task
- [ ] Another task
  - [x] Nested completed

Renders as interactive checkboxes on GitHub (click to toggle). On other GFM-compatible renderers, they typically render as static checkmarks.

Use cases: issue checklists, PR checklists, README progress trackers.

Strikethrough

This is ~~deleted text~~ and this is normal.

Double tilde. Single tilde doesn't work (that's Slack syntax — seeMarkdown in Slack).

Bare URL: https://example.com
GitHub handle: @username
Issue reference: #1234

In CommonMark, bare URLs render as plain text. In GFM, they're auto-detected and linked. GitHub additionally auto-links@username to GitHub profiles and#1234 to issues in the same repo.

Disallowed raw HTML

GFM disallows certain HTML tags (<script>,<iframe>,<style>, etc.) by default. CommonMark passes them through unchanged. This is the main security difference — GFM is safer when rendering untrusted input. (You should still sanitize after rendering. Never trust the renderer alone — seeMarkdown to HTML for the full security story.)

Emoji shortcodes (GitHub-specific)

I'm :rocket: about this :tada:

On GitHub,:rocket: and:tada: render as the corresponding emoji. Strictly speaking, this is a GitHub-specific extension on top of GFM, not part of the GFM spec itself. Most other GFM renderers don't support emoji shortcodes.

What's in GitHub but not in GFM

GitHub's renderer adds features beyond GFM:

  • Math (LaTeX inside$…$ or$$…$$ blocks) — GitHub 2022+
  • Mermaid diagrams (fenced code block withmermaid language) — GitHub 2022+
  • Geographic data (GeoJSON / TopoJSON / KML rendered as a map)
  • 3D models (STL files rendered as 3D)
  • CSV / TSV (rendered as tables, paginated)

These are GitHub-specific. They don't render on GitLab, Codeberg, or other GFM hosts.

Renderers that support GFM

RendererGFM tablesTask listsStrikethroughAutolinks
GitHub
GitLab
Discord
Slack✅ (single ~)
Reddit
Stack Overflow
Notion
Confluencepartial
Obsidian

If you're writing Markdown that has to render the same on multiple platforms, the cross-platform safe subset is: CommonMark + tables + strikethrough. Skip task lists for Discord/Slack/Reddit. Skip autolinks where you need controlled link behavior.

Enabling GFM in libraries

  • markdown-it (JS):npm install markdown-it-gfm-tables markdown-it-task-lists and plug in.
  • marked (JS): GFM is the default.
  • remark (JS):remarkPlugins={[remarkGfm]} inreact-markdown.
  • Pythonmarkdown:extensions=['tables', 'fenced_code'] covers most of GFM. Task lists need a separate extension.
  • Pandoc: input formatgfm ormarkdown_github.
  • Ruby kramdown: GFM is one of the input parsers.
  • MkDocs: tables work; task lists needpymdownx.tasklist.

SeeMarkdown to HTML for the per-library setup.

Common GFM gotchas

  1. Tables silently fail. A table with a missing trailing pipe or mismatched column count just doesn't render — no error, no warning. The whole thing shows as plain text.
  2. Task lists need GFM-aware renderers. They render as[ ] characters everywhere else.
  3. Autolinked URLs eat trailing punctuation.https://example.com. (with a period) sometimes includes the period in the link, sometimes doesn't, depending on the renderer.
  4. Emoji shortcodes are GitHub-only. Don't rely on them in portable content.

When to write GFM vs CommonMark

  • For GitHub READMEs, GitLab wiki pages, docs sites with GFM-compatible renderers: write GFM. The features (tables, task lists) are too useful to skip.
  • For maximum portability across unknown renderers: write CommonMark + tables only. Skip task lists, skip strikethrough, skip autolinks. Slightly more verbose but renders everywhere.
  • For chat tools (Discord, Slack): write the platform's specific dialect. SeeMarkdown in Discord andMarkdown in Slack.

Try Markdown Tidy free

Paste markdown, get a polished document — no signup required.