GFM Cheat Sheet: GitHub Flavored Markdown Tables, Alerts & Syntax

GitHub's own spec for GFM is the authoritative reference, but it reads like a grammar document — precise, and not exactly built for someone who just needs to remember the table syntax before a PR deadline. This page is the version built for that moment: every GFM extension with a copy-paste example, what it looks like once GitHub actually renders it, and where it silently stops working outside GitHub.

GFM is short for GitHub Flavored Markdown — the exact Markdown dialect GitHub uses everywhere on the platform. Standard Markdown (CommonMark) covers headings, lists, links, and emphasis, but the moment you write a README, open an issue, or review a pull request on GitHub, you are using GFM's extensions on top of that base: tables, task lists, strikethrough, autolinks, syntax-highlighted code fences, footnotes, and alert boxes.

CommonMark (base)# Headings *emphasis*- lists [links](url)`code` > blockquote+GFM extensionsTables · Task listsStrikethrough · AutolinksSyntax-highlighted fencesFootnotes · Alerts= GFM

GFM vs. Plain CommonMark: Feature by Feature

Every GFM document is valid CommonMark's superset, not the other way around — write plain CommonMark and it works everywhere; write GFM tables or alerts and they degrade to plain text (or a plain blockquote) anywhere that isn't GitHub.

FeatureCommonMarkGFM
Headings, emphasis, links, listsYesYes (inherited)
Fenced code blocksYes (parsing only)Yes + Linguist syntax highlighting
TablesNoYes
Task list checkboxesNoYes (interactive in issues/PRs)
Strikethrough (~~text~~)NoYes
Autolinked bare URLsNo (needs <angle brackets>)Yes (automatic)
FootnotesNoYes (added 2021)
Alerts ([!NOTE], [!WARNING])NoYes, GitHub-only (added 2023)
@mentions and #issue autolinksNoYes, GitHub-only

Tables and Alignment Syntax

Tables are the most-used GFM extension. Columns are separated by pipes, and the second row of hyphens marks the header. Colons in that separator row control alignment: :--- aligns left, :---: centers, and ---: aligns right.

| Feature       | Status   | Coverage |
| :------------ | :------: | -------: |
| Login         | Done     |      95% |
| Payments      | Review   |      80% |
| Notifications | Planned  |       0% |

Here is what that source actually renders to on GitHub:

FeatureStatusCoverage
LoginDone95%
PaymentsReview80%
NotificationsPlanned0%

↑ Rendered example (GitHub's actual UI, reproduced here — not a live GitHub page)

You do not need to line up the pipes perfectly — GitHub renders ragged tables fine — but aligned source is much easier to review in a diff. Outer pipes are optional, and you can use inline formatting (bold, code, links) inside cells. What you cannot do is merge cells or add multi-line content; for that you need HTML or a different structure.

Task Lists and Strikethrough

Task lists turn bullet items into checkboxes. In issues and pull requests they are interactive — clicking the checkbox updates the source, and GitHub shows a progress count like "3 of 5 tasks" on the issue card.

- [x] Write the migration script
- [x] Add unit tests
- [ ] Update the API docs
- [ ] Deploy to staging

Use ~~strikethrough~~ for text that is no longer valid.

Rendered, that becomes a real checklist with a progress count GitHub tracks automatically:

2 of 4 tasks
Write the migration script
Add unit tests
Update the API docs
Deploy to staging

↑ Rendered example — on an issue or PR, each box is clickable and the "2 of 4" count updates live

Strikethrough uses double tildes: ~~old plan~~ renders with a line through it. It is useful for showing superseded decisions without deleting the history of the discussion.

Autolinks, Mentions, and Issue References

GFM automatically converts several plain-text patterns into links, no bracket syntax required:

  • URLs — pasting https://dev-brains-ai.com becomes a clickable link automatically
  • @mentions — typing @username links to a profile and notifies that person or team
  • Issue and PR references#42 links to issue or PR number 42 in the same repo; owner/repo#42 works across repositories
  • Commit SHAs — pasting a full or short commit hash links to that commit
  • Closing keywords — writing "Fixes #42" in a PR description automatically closes issue 42 when the PR merges

These references are the glue of a GitHub workflow: they build a cross-linked trail between bugs, fixes, and releases without any manual effort.

Code Fences with Syntax Highlighting

Fenced code blocks use three backticks. Add a language identifier immediately after the opening fence and GitHub applies full syntax highlighting:

```javascript
const total = items.reduce((sum, item) => sum + item.price, 0);
```

```diff
- const timeout = 3000;
+ const timeout = 10000;
```

GitHub supports hundreds of languages via Linguist — js, python, sql, bash, json, yaml, and more. The diff language is especially handy in PR discussions: lines starting with a plus render green and lines starting with a minus render red.

Footnotes and Alerts

Footnotes let you add references without cluttering the main text. Alerts (also called admonitions) render as colored callout boxes and are perfect for warnings in READMEs:

Here is a claim that needs a source.[^1]

[^1]: The footnote text appears at the bottom of the page.

> [!NOTE]
> Helpful information users should know.

> [!WARNING]
> Critical content demanding immediate attention.

Five alert types are supported: [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], and [!CAUTION]. Each renders with its own icon and color. Alerts are a GitHub-specific extension — other Markdown renderers will show them as plain blockquotes, so do not rely on them outside GitHub.

Putting It Together: A Real PR Description

Here is what most of these extensions look like combined in a single, realistic pull request description — the kind of GFM you would actually write day to day:

## Summary
Fixes #128 — checkout was failing when `discountCode` was empty.

## Changes
- [x] Guard against empty discount codes in `applyDiscount()`
- [x] Add unit tests for the empty and null cases
- [ ] Update the API docs (follow-up PR)

## Before / after

| Input          | Before        | After     |
| :------------- | :-----------: | --------: |
| `""`           | 500 error     | No-op     |
| `null`         | 500 error     | No-op     |
| `"SAVE10"`      | Applied       | Applied   |

> [!WARNING]
> This changes the return type of `applyDiscount()` from `void` to `Result`. cc @teammate

```diff
- function applyDiscount(code) {
+ function applyDiscount(code) {
+   if (!code) return { applied: false };
    ...
```

Notice how little of this is prose — the task list gives reviewers a progress checklist, the table replaces a paragraph of "before this bug, X happened," the alert calls out the one thing a reviewer must not miss, and the diff fence shows the fix without linking out to the full file.

A Second Example: A Bug Report Issue

PR descriptions lean on tables and diffs; a good bug report leans harder on footnotes and autolinked references instead:

## Bug: export button silently does nothing on Safari

**Steps to reproduce**
1. Open the dashboard on Safari 17[^1]
2. Click "Export CSV"
3. Nothing happens — no download, no error in console

**Expected:** a CSV file downloads
**Actual:** the click is silently swallowed

Related to #204, which fixed the same symptom on Firefox last month.
Introduced somewhere around @teammate's PR #198.

[^1]: Not reproducible on Chrome or Firefox — appears Safari-specific.

The footnote keeps the "which browsers" caveat out of the main flow without deleting it, and #204 / #198 autolink straight to those issues and PRs — anyone reading this six months later can follow the whole history in two clicks.

Common GFM Mistakes

  • Missing blank line before a table. GFM tables must be preceded by a blank line, or GitHub renders the pipes as plain text instead of a table.
  • No space inside task-list brackets. -[x] does not render as a checkbox — it must be - [x] with a space after the dash.
  • Forgetting the code fence language. Triple backticks with no language tag (just ```) still renders a code block, but without syntax highlighting — always add js, python, diff, etc.
  • Using tabs instead of spaces for nested lists. GFM's parser is inconsistent with tab-indented nested lists across contexts; use spaces (typically 2 or 4) to avoid list items silently un-nesting.
  • Expecting alerts to work outside GitHub. > [!NOTE] syntax is GitHub-specific — on GitLab, npm, or a static site it just renders as a plain blockquote starting with the literal text "[!NOTE]".
  • Single tilde for strikethrough. GFM strikethrough needs double tildes — ~~text~~ — a single tilde does nothing.

Where GFM Works (and Where It Does Not)

  • README and docs files — tables, fences, footnotes, and alerts all render; task lists show as static checkboxes. See our guide to writing a great README for how to structure one.
  • Issues and pull requests — everything works, and task lists plus mentions become interactive. For a deeper walkthrough, see writing GitHub issues and PRs with Markdown.
  • Discussions, wikis, and gists — full GFM support
  • Commit messages — issue references link, but most formatting is not rendered in every view
  • Outside GitHub — GitLab and Bitbucket support most GFM; static site generators vary, so test tables and footnotes before publishing

When in doubt, preview before you publish. A live previewer such as the free Dev Brains AI Markdown Previewer shows exactly how tables, task lists, and code fences will render as you type.

Frequently Asked Questions

What is GitHub Flavored Markdown?

GitHub Flavored Markdown (GFM) is GitHub's extension of standard Markdown. It adds tables, task lists, strikethrough, autolinks, syntax-highlighted code fences, footnotes, and alerts on top of the CommonMark specification.

How do I make a table in GitHub Markdown?

Use pipes to separate columns and hyphens for the header row. Add colons to the separator row to control alignment: :--- for left, :---: for center, and ---: for right alignment.

Where does GitHub Flavored Markdown work?

GFM renders in README files, issues, pull requests, discussions, wikis, gists, and comments on GitHub. Some features like task lists and mentions are interactive only in issues and pull requests.

What does GFM stand for?

GFM stands for GitHub Flavored Markdown — the specific Markdown dialect GitHub uses across the whole platform. It is a superset of CommonMark, meaning every standard Markdown document is also valid GFM.

Is GFM different from regular Markdown?

Yes. Regular Markdown (CommonMark) covers headings, lists, links, and emphasis. GFM adds tables, task lists, strikethrough, autolinked issue references, syntax-highlighted code fences, footnotes, and alert boxes on top of that base.

Will GFM tables and alerts work on GitLab or a static site?

Tables usually work on GitLab and most static site generators, since they were widely copied. Alerts ([!NOTE], [!WARNING]) will not — that syntax is GitHub-specific and renders as a plain blockquote with the literal "[!NOTE]" text everywhere else. Always test on the actual target platform before relying on GFM-only features.

Does CommonMark support tables or task lists?

No. Tables, task-list checkboxes, strikethrough, footnotes, and alerts are all GFM extensions, not part of the core CommonMark specification. A CommonMark-only renderer will show GFM table syntax as plain text with pipe characters rather than an actual table.

Try the Free Markdown Previewer

Write GFM tables, task lists, and code fences with a live side-by-side preview in your browser. No signup, no cost.

Related articles