GitHub Flavored Markdown: What It Adds and Why It Matters
GitHub Flavored Markdown: What It Adds and Why It Matters
GitHub Flavored Markdown (GFM) is the dialect of markdown used across GitHub for README files, issues, pull requests, wikis, and comments. If you write on GitHub regularly, understanding what GFM adds over standard CommonMark will save you time and make your documents more useful.
Quick Answer: GitHub Flavored Markdown (GFM) extends CommonMark with 6 additional features: tables, strikethrough, task lists, autolinks, syntax-highlighted fenced code blocks, and HTML filtering. It is formally specified at github.github.com/gfm and is supported by over 100 million GitHub repositories worldwide.
What Is GitHub Flavored Markdown?
GFM is a formal specification maintained by GitHub, built on top of CommonMark. CommonMark is the standardized version of the original markdown spec, designed to eliminate ambiguity. GFM extends CommonMark with a set of features that address practical needs for software documentation: tables, task lists, strikethrough text, autolinks, and syntax-highlighted fenced code blocks.
The full spec is published at github.github.com/gfm, which makes GFM one of the few markdown dialects with an actual machine-readable specification.
How Does GFM Differ from CommonMark?
CommonMark defines the core: paragraphs, headings, bold, italic, blockquotes, lists, inline code, and fenced code blocks. GFM adds the following on top:
| Feature | CommonMark | GFM |
|---|---|---|
| Tables | No | Yes |
| Strikethrough | No | Yes |
| Task lists | No | Yes |
| Autolinks (bare URLs) | Limited | Yes |
| Disallowed HTML | No restriction | Filtered |
| Fenced code with language | No | Yes |
For a broader look at what features exist beyond the CommonMark baseline, see the guide to Markdown Extended Syntax.
How Do You Create Tables in GFM?
Tables are one of the most-used GFM extensions. The syntax uses pipes and hyphens:
| Name | Role | Status |
|------------|------------|---------|
| Alice | Engineer | Active |
| Bob | Designer | Active |
| Carol | Manager | On leave|
Rendered output:
| Name | Role | Status |
|---|---|---|
| Alice | Engineer | Active |
| Bob | Designer | Active |
| Carol | Manager | On leave |
Column alignment is controlled by the position of the colon in the separator row:
| Left | Center | Right |
|:-----|:------:|------:|
| a | b | c |
For a deeper look at table syntax options, see the Markdown Tables Guide.
What Is Strikethrough in GFM?
GFM adds strikethrough using double tildes:
~~This text is no longer relevant.~~
This renders as: This text is no longer relevant.
Useful for showing deprecated options, corrected errors, or completed items in documentation.
How Do Task Lists Work in GFM?
Task lists are a GFM-specific syntax that renders interactive checkboxes in GitHub UI:
- [x] Set up repository
- [x] Write README
- [ ] Add CI pipeline
- [ ] Write tests
These render as clickable checkboxes in GitHub issues and pull requests. In a README, they display as static visual indicators of completion status. GitHub reports that task lists in issues are used by millions of teams to track project progress without leaving the repository. For a full breakdown of this feature, see the post on Markdown Task Lists.
What Are GFM Autolinks?
GFM automatically turns bare URLs into clickable links without requiring angle brackets or markdown link syntax:
Visit https://example.com for more information.
CommonMark requires wrapping the URL: <https://example.com>. GFM handles both styles, but bare URL autolinks are a GFM-only feature that makes writing issue comments and discussions faster.
How Do Fenced Code Blocks Work with Syntax Highlighting?
Standard CommonMark supports fenced code blocks using triple backticks or tildes, but does not specify language identifiers. GFM formalizes the language identifier and GitHub renders it with full syntax highlighting. GitHub supports over 500 language identifiers for syntax highlighting, including TypeScript, Go, Rust, SQL, YAML, JSON, and many others.
Example: JavaScript
```javascript
function greet(name) {
return `Hello, ${name}!`;
}
```
Example: Python
```python
def greet(name: str) -> str:
return f"Hello, {name}!"
```
Example: Bash
```bash
#!/bin/bash
echo "Deploying to production..."
git pull origin main
```
Adding the language identifier is always worth doing since it improves readability for anyone reviewing the code.
How Does GFM Handle Raw HTML?
Unlike standard markdown, GFM filters (sanitizes) raw HTML in certain contexts. On GitHub.com, a subset of HTML tags is allowed: <details>, <summary>, <kbd>, <code>, <sup>, <sub>, and a few others. Tags like <script> and <style> are stripped entirely.
The commonly used <details> and <summary> tags let you create collapsible sections in a README:
<details>
<summary>Click to expand</summary>
Content that is hidden by default until the user clicks.
</details>
This is a practical pattern for long READMEs where you want to hide verbose installation steps or configuration examples.
How Should You Structure a GFM README?
Your repository’s README.md is typically the first thing a visitor sees. Here is a structure that takes advantage of GFM features effectively:
# Project Name
Short description of what this does.
## Features
- [x] Core feature A
- [x] Core feature B
- [ ] Planned feature C
## Installation
```bash
npm install my-package
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
| timeout | number | 3000 | Request timeout (ms) |
| retries | number | 3 | Retry attempts |
| verbose | boolean | false | Enable debug output |
Changelog
v0.9 (deprecated) Use v1.0 instead.
This structure uses tables for configuration options, task lists for roadmap status, strikethrough for deprecated versions, and fenced code blocks with language identifiers. These elements all render cleanly on GitHub without any special configuration.
## Where Is GFM Supported Outside GitHub?
GFM is not exclusive to GitHub. Many tools and platforms support it:
- **GitLab** supports GFM with minor variations (GitLab also adds math blocks and Mermaid diagrams natively).
- **VS Code** renders GFM in its markdown preview.
- **Obsidian** supports most GFM syntax.
- **Pandoc** can parse GFM with the `--from=gfm` flag.
- **markdown-it** supports GFM tables and strikethrough via plugins.
The GFM spec is stable enough that most modern markdown processors either support it natively or provide plugins for the most popular extensions.
## Practical Tips for Writing GFM
1. Always add a language identifier to fenced code blocks. It costs nothing and improves readability.
2. Use task lists in issues to break work into trackable steps. GitHub allows editing checkbox state directly without touching the markdown source.
3. Tables work best with short cell content. For complex data, consider linking to an external document instead.
4. Use `<details>` to collapse lengthy sections like full configuration examples or long changelogs.
5. Autolinks work for plain URLs but markdown link syntax `[text](url)` is better when you want descriptive anchor text.
---
If you want to write and preview GFM syntax before pasting it into GitHub, [edtr.md](/app) renders tables, task lists, strikethrough, and fenced code blocks in real time. Open it in your browser and start writing.
Try it yourself
Open edtr.md and start writing Markdown with live preview, diagrams, math, and PDF export. Free, no sign-up.
Open editor