GFM vs CommonMark: What Is the Difference?
When John Gruber published the original Markdown specification in 2004 it was intentionally informal, leaving many edge cases undefined. Over the next decade dozens of incompatible Markdown dialects appeared. In 2014 a group of engineers formalised the specification into CommonMark, an unambiguous, machine-readable standard that any parser can implement deterministically.
GitHub had already been shipping its own extensions for years. In 2017 it published the GFM specification as a strict superset of CommonMark, documenting every extension it adds. The relationship is simple:
- All valid CommonMark is valid GFM.
- GFM adds six extension categories: tables, task list items, strikethrough, autolinks (extended), disallowed raw HTML, and footnotes (draft).
- Emoji shortcodes are a GitHub platform feature layered on top of the GFM parser — technically outside the spec but universally associated with GFM environments.
Understanding this layering helps when something renders on GitHub but not on another platform: the platform may support the CommonMark baseline without the GFM extensions, or it may add its own on top.
Task Lists / Checkboxes
Task lists let you embed interactive checklists directly in Markdown. They are most useful in GitHub Issues and Pull Request descriptions, where GitHub renders them as real checkboxes and tracks completion percentages.
The syntax extends an ordinary unordered list:
- [x] Research topic
- [x] Write first draft
- [ ] Add code examples
- [ ] Peer review
- [ ] PublishRules to remember:
- The brackets must immediately follow the list marker and a space:
- [ ]or- [x]. - Only
x(lowercase) marks an item as complete. A capitalXis accepted by most renderers but is not in the spec. - Task lists can be nested — indent by two or four spaces to create a sub-list under a parent task.
- On GitHub, clicking a rendered checkbox automatically commits an edit to the underlying Markdown source.
Outside GitHub, task list rendering varies. Most editors (VS Code, Typora, Obsidian) render the checkboxes visually but do not make them interactive. The LiveMarkdownText editor renders GFM task lists in the live preview so you can see exactly how they will look before pasting into GitHub.
Tables
GFM tables are one of the most-used extensions. They use pipe characters (|) as column separators and a separator row of dashes to divide the header from the body.
Minimal syntax:
| Name | Role | Status |
| ------- | --------- | ------- |
| Alice | Engineer | Active |
| Bob | Designer | On leave|Column Alignment
Add a colon to the separator row to control alignment per column:
| Left | Center | Right |
| :------ | :------: | ------: |
| text | text | text |:---— left-align (default when no colon is present):---:— center-align---:— right-align
Practical Tips
- You do not need to pad cells with spaces — GFM ignores extra whitespace inside cells. Consistent spacing is purely for source readability.
- Leading and trailing pipe characters are optional but recommended for clarity.
- Cells can contain inline Markdown: bold, italic, inline code, and links all work inside table cells.
- You cannot merge cells (colspan/rowspan). For complex layouts, consider raw HTML or restructuring the content.
Strikethrough Text
Wrap text in double tildes to render it with a horizontal strikethrough line, conveying deletion or obsolescence:
The price is ~~$50~~ $35.Rendered output: The price is $50 $35.
Single tildes (~text~) are not part of the GFM spec and are not guaranteed to produce strikethrough. Always use double tildes for reliable cross-platform rendering. Strikethrough is widely used in changelogs, deprecation notices, and edited comments.
Autolinks
CommonMark supports autolinks inside angle brackets: <https://example.com>. GFM extends this with extended autolinks — bare URLs and email addresses are automatically linked without any special delimiters:
Visit https://example.com for more information.
Contact support at hello@example.com.GFM's autolink rules are deliberately conservative to avoid false positives. A URL is only linked when it begins with http://, https://, ftp://, or when it looks like a valid domain followed by a path. Trailing punctuation (periods, commas, closing parentheses) is stripped from the linked text if it would produce an invalid URL.
Note that bare autolinks do not work in all GFM environments — some renderers require the angle-bracket form. When in doubt, use an explicit Markdown link: [link text](https://example.com).
Fenced Code Blocks with Syntax Highlighting
Fenced code blocks were adopted into CommonMark and are one of the most important GFM improvements over the original Markdown spec. Instead of indenting every line by four spaces, you wrap the block in triple backticks or triple tildes:
```javascript
function greet(name) {
return `Hello, ${name}!`;
}
```The optional language identifier immediately following the opening fence tells renderers which grammar to use for syntax highlighting. GitHub supports hundreds of identifiers via the Linguist library. Common ones include:
javascript/js— JavaScripttypescript/ts— TypeScriptpython/py— Pythonbash/sh— Shell scriptscss,html,json,yaml,sql— markup and data formatsdiff— unified diff output with green/red highlightingtext/plaintext— disables highlighting explicitly
Triple tildes work identically to triple backticks and are useful when your code block itself contains backtick sequences. You can also use four or more backticks if your content contains a triple-backtick fence.
Syntax highlighting is a renderer concern — the GFM spec only governs how fences are parsed, not how highlighting is applied. GitHub uses Linguist; other platforms use Prism, Highlight.js, or Shiki.
Footnotes
Footnotes are a GFM draft extension (not in the official 0.29 spec release but supported by GitHub and many other renderers). They let you attach numbered references to inline content without cluttering the main text:
GFM was formalised in 2017.[^1] It builds on CommonMark.[^note]
[^1]: See the official GFM specification at github.github.com/gfm/
[^note]: CommonMark was published in 2014 by a group including John MacFarlane.The footnote reference [^1] appears inline as a superscript number linked to the footnote definition at the bottom of the rendered document. Footnote identifiers can be numbers or words — the rendered output always uses sequential numbers regardless of identifier names.
Footnote definitions can span multiple lines and even contain block-level content such as paragraphs and lists, as long as continuation lines are indented by four spaces.
Support varies: GitHub renders footnotes; many other GFM renderers do not. Always verify footnote support in your target platform before relying on them.
Emoji Shortcodes
While not part of the formal GFM specification, emoji shortcodes are universally associated with the GitHub Markdown experience. Wrap an emoji name in colons to insert the corresponding Unicode emoji:
:rocket: :white_check_mark: :warning: :bug: :sparkles:Rendered: rocket, white_check_mark, warning, bug, sparkles (the actual emoji glyphs appear on GitHub and other supporting platforms).
GitHub's full emoji list contains over 1,800 shortcodes. You can browse them at emoji-cheat-sheet. Some useful categories for technical writing:
- Status indicators:
:white_check_mark:,:x:,:warning:,:information_source: - Development:
:bug:,:rocket:,:construction:,:sparkles: - Reactions:
:+1:,:-1:,:tada:,:eyes:
Emoji shortcodes are processed by the platform layer, not the GFM parser. They will not render outside of platforms that explicitly support them (GitHub, GitLab, Slack, etc.). In plain Markdown-to-HTML pipelines without emoji processing, the raw shortcode text will appear as-is.
Where Is GFM Used?
GFM has become the de-facto extended Markdown standard across the software development ecosystem:
- GitHub — all content: README files, issues, pull requests, wiki pages, discussions, release notes.
- GitLab — full GFM support plus some GitLab-specific extensions (quick actions, references).
- Gitea & Forgejo — open-source Git platforms with GFM support.
- VS Code — the built-in Markdown preview renders GFM including tables, task lists, and strikethrough.
- Obsidian — GFM tables, task lists, and strikethrough are supported; footnotes and emoji shortcodes via community plugins.
- Typora & Zettlr — WYSIWYG Markdown editors with full GFM rendering.
- Static site generators — Jekyll (via kramdown + GFM mode), Hugo (via Goldmark), Docusaurus, VitePress, and others support GFM by default or via configuration.
- Slack & Discord — partial support: fenced code blocks and some inline formatting work, but tables and task lists do not.
- Jira & Confluence — recent versions accept Markdown paste with partial GFM support.
When writing Markdown for a new platform, always check its documentation for which GFM extensions are supported. Tables, task lists, strikethrough, and fenced code blocks have the broadest support. Footnotes and emoji shortcodes are the least universally supported.
Putting It All Together: A GFM Cheat Sheet
Here is a compact reference combining all GFM extensions discussed in this guide:
## Task List
- [x] Done
- [ ] Pending
## Table with Alignment
| Feature | CommonMark | GFM |
| :------------ | :--------: | --: |
| Task lists | No | Yes |
| Tables | No | Yes |
| Strikethrough | No | Yes |
| Autolinks | Partial | Yes |
| Footnotes | No | Yes |
## Strikethrough
~~deprecated API~~ use newApi() instead
## Autolink
Visit https://example.com for docs.
## Fenced Code Block
```python
def hello(name: str) -> str:
return f"Hello, {name}!"
```
## Footnote
See the specification.[^spec]
[^spec]: github.github.com/gfm/
## Emoji
:rocket: Deployment complete!GFM Best Practices
- Always specify a language identifier on fenced code blocks. Even
textis better than nothing — it signals intent and disables auto-detection heuristics that can produce wrong highlighting. - Keep table source readable. Align pipes and pad cells in source so reviewers can scan the raw Markdown in diffs without rendering it.
- Use task lists for actionable items only. In long documents, task lists with many items can be noisy. Reserve them for genuine checklists in issues and PR descriptions.
- Test footnotes in your target renderer. Because footnotes are a draft extension, they are the most likely to break silently on non-GitHub platforms.
- Prefer explicit links over bare autolinks for important URLs. Bare autolinks can be inadvertently broken by line wrapping or punctuation adjacency.
- Use strikethrough sparingly. In documentation, strikethrough signals deletion. Overuse dilutes its meaning. For deprecated API docs, pair it with a note explaining the replacement.