Markdown Flavors: GFM vs CommonMark
Reviewed & published by Brayan K
By the end of this lesson you'll know why the same Markdown can render differently in different tools — and how to tell core CommonMark apart from GitHub Flavored Markdown so you can write documents that stay portable.
Part of the free Markdown course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn
- What CommonMark is and why it was created
- The features GitHub Flavored Markdown adds on top
- How the original Gruber Markdown relates to today's flavors
- Where MultiMarkdown and Pandoc fit in
- Why flavors diverged in the first place
- How to write portable Markdown that works everywhere
💡 Real-World Analogy
Markdown flavors are like dialects of one language. Everyone agrees on the core vocabulary — headings, bold, lists — so a sentence in that core is understood everywhere. But each region added its own slang: GitHub says "tables and checkboxes", Pandoc says "footnotes and citations". You're still speaking Markdown, but a phrase from one dialect may get blank looks somewhere else. Writing portably means sticking to the shared vocabulary so no audience is left confused.
1. The Original and CommonMark
Markdown was created by John Gruber in 2004 (with help from Aaron Swartz) as a simple way to write formatted text. The original description was deliberately informal, which left many edge cases undefined — so different tools interpreted them differently. CommonMark arrived later as a strict specification: a precise, testable definition of how Markdown should behave, so the same input gives the same output across compliant tools.
Core Markdown source (portable)
# Heading
**bold** and *italic*
- a bullet list
- another item
[a link](https://example.com)
\`\`\`
a fenced code block
\`\`\`Renders the same nearly everywhere
- a bullet list
- another item
a fenced code block2. GitHub Flavored Markdown (GFM)
GitHub Flavored Markdown is defined as a strict superset of CommonMark — it includes everything CommonMark does and adds popular extensions on top: tables, task lists (- [ ]), strikethrough (~~text~~), autolinks (bare URLs become clickable), and fenced code with language highlighting. These are wildly useful but not part of the core spec, so they may not render on a plain CommonMark viewer.
~~struck through~~ text (GFM strikethrough)
- [x] a done task
- [ ] a pending task
| Col A | Col B |
|-------|-------|
| 1 | 2 |
Autolink: https://example.com becomes clickable on its own.Renders on GitHub / GFM tools
struck through text (GFM strikethrough)
- a pending task
| Col A | Col B |
|---|---|
| 1 | 2 |
🎯 Your Turn #1: portable core only
Fill in the blanks so the program prints Markdown using only the common core — a heading and a bullet list. None of it should depend on a specific flavor.
// 🎯 YOUR TURN — write PORTABLE (core) Markdown only.
// Use just headings, emphasis, lists, and links: features in the
// common core that render almost everywhere. Fill in each ___.
const title = "___"; // 👉 a heading, e.g. My Notes
const point = "___"; // 👉 a bullet, e.g. Stays portable
console.log("# " + title);
console.log("");
console.log("- " + point);
console.log("- Works on CommonMark and GFM alike");
// ✅ Expected printed source (example):
// # My Notes
//
// - Stays portable
// - Works on CommonMark and GFM alike
//
// None of these lines depend on a specific flavor.3. Why Flavors Diverged
The original Markdown was a description, not a rigorous standard, so it left questions unanswered: how many spaces nest a list? What happens with overlapping emphasis? Each implementation answered differently, and many added new features their users wanted — tables, footnotes, math. The result is a family of flavors: CommonMark (the unifying spec), GFM (CommonMark plus GitHub's extras), MultiMarkdown (footnotes, tables, metadata, citations), and Pandoc Markdown (a very extensible variant aimed at document conversion).
The family at a glance
- Gruber Markdown (2004) — the original, loosely specified
- CommonMark — a strict, testable standard for the core
- GFM — CommonMark + tables, task lists, strikethrough, autolinks
- MultiMarkdown — adds footnotes, tables, metadata, citations
- Pandoc Markdown — highly extensible, built for converting between formats
Here's a worked example that prints Markdown source and labels the flavor each line needs. Run it, read the comments, then paste the core block and the GFM block into different viewers to see which lines render.
## Core CommonMark (works almost everywhere)
# Title
**bold**, *italic*, and [a link](https://example.com)
## GFM extensions (need a GFM processor)
~~strikethrough~~
- [x] task list item
| A | B |
|---|---|
| 1 | 2 |
<!-- ✅ Expected result, rendered:
h2 -> text: Core CommonMark (works almost everywhere)
h1 -> count: 1
h2 -> count: 2
p -> count: 2
ul -> count: 1
li -> count: 1
table -> count: 1
tr -> count: 2
td -> count: 2
th -> count: 2
a -> count: 1
strong -> count: 1
em -> count: 1
del -> count: 1
input[type="checkbox"] -> count: 1
-->🎯 Your Turn #2: a GFM-only feature
Fill in the blanks so the program prints a strikethrough price change. Remember: ~~text~~ is a GFM extension, so it may not render on a core-only viewer.
// 🎯 YOUR TURN — write a GFM-only feature.
// Strikethrough uses a pair of tildes on each side; it is NOT in the
// original Markdown or guaranteed in plain CommonMark. Fill in each ___.
const oldPrice = "___"; // 👉 a price to cross out, e.g. 50
const newPrice = "___"; // 👉 the new price, e.g. 30
console.log("Now ~~" + oldPrice + "~~ " + newPrice + "!");
// ✅ Expected printed source (example):
// Now ~~50~~ 30!
//
// On GitHub the 50 shows struck through; on a core-only viewer the
// tildes may appear literally because strikethrough is a GFM extension.4. Writing Portable Markdown
To make a document render the same everywhere, lean on the shared core: headings, paragraphs, emphasis, lists, links, images, blockquotes, and fenced code. These are defined by CommonMark and supported almost universally. Reach for flavor-specific syntax (GFM tables, task lists, math) only when you know your audience's platform supports it — or provide a plain-core fallback.
Common Errors (and the fix)
- My table is plain text elsewhere. Tables are a GFM extension, not core CommonMark. On non-GFM viewers, use a code block or a simple list instead.
- Tildes show literally. Strikethrough ~~...~~ is GFM-only. Drop it for core-only audiences, or move the doc to GitHub.
- Checkboxes render as [ ] text. Task lists are GFM. Plain bullets are the portable fallback.
- Bare URL isn't clickable. Autolinking bare URLs is a GFM behaviour; in core, wrap the URL: <https://example.com> or use [text](url).
- Same file, different output. You're relying on a flavor the second tool doesn't share. Identify which feature is flavor-specific and replace it with core syntax.
📋 Quick Reference — Flavors
| Feature | Flavor |
|---|---|
| Headings, emphasis, lists, links | Core (CommonMark) |
| Fenced code blocks | Core (CommonMark) |
| Tables | GFM extension |
| Task lists - [ ] | GFM extension |
| Strikethrough ~~ ~~ | GFM extension |
| Footnotes, citations | MultiMarkdown / Pandoc |
| Many output formats | Pandoc |
Mini-Challenge: A Portability Report
No blanks this time — just a brief and an outline. Use console.log to print a short note using only core CommonMark (heading, emphasis, list, link), then add one clearly-commented GFM-only line and note that it needs a GFM processor.
// 🎯 MINI-CHALLENGE: print a "portability report" block.
// Build (with console.log) the SOURCE for a short note that uses ONLY
// core CommonMark, so it renders the same everywhere. Include:
// 1. An H2 heading (## ...)
// 2. A short paragraph with **bold** and *italic*
// 3. A 3-item bullet list
// 4. One [link](url)
// Then add ONE clearly-commented GFM-only line (e.g. a ~~strikethrough~~)
// and note in a comment that it needs a GFM processor.
//
// ✅ The core lines render anywhere; the GFM line needs GitHub.
// your code herePro Tips
- 💡 Know your target. Writing for GitHub? GFM is fine. Writing for an unknown viewer? Stay in the core.
- 💡 Prefer reference links and core lists. They render identically across flavors, unlike tables and task lists.
- 💡 Test in two tools. Render the same file in CommonMark and in GitHub to spot flavor-specific lines.
- 💡 Reach for Pandoc to convert. When you must move Markdown to DOCX, PDF, or LaTeX, Pandoc handles the most formats.
Frequently Asked Questions
Q: Is GFM a totally separate language from CommonMark?
No. GFM is a strict superset of CommonMark — it adds features but keeps full compatibility, so any CommonMark document is also valid GFM.
Q: Which flavor should I learn first?
The core, as defined by CommonMark. Once that's solid, GFM's additions (tables, task lists, strikethrough) are small and easy to layer on.
Q: Why does my Markdown look different on two sites?
They run different processors. A line using a GFM or Pandoc extension renders on a tool that supports it but not on a plain CommonMark one.
Q: Where do footnotes fit?
Footnotes aren't in core CommonMark; they come from MultiMarkdown and Pandoc, and GitHub supports them too. They're a flavor feature, so check support.
Lesson Complete! 🎉
- ✅ CommonMark is the strict, standardised spec for core Markdown
- ✅ GFM is a superset adding tables, task lists, strikethrough, and autolinks
- ✅ The original Gruber Markdown was loosely defined, so flavors diverged
- ✅ MultiMarkdown and Pandoc add footnotes, citations, and broad conversion
- ✅ Portable Markdown sticks to the shared core that renders everywhere
Where to go next: now turn your Markdown into a real site. Continue to Publishing with MkDocs, Hugo and Jekyll to convert .md files into HTML pages.
Practice quiz
What is CommonMark?
- A strict, standardised specification of Markdown
- A GitHub-only feature
- A diagram tool
- A spreadsheet format
Answer: A strict, standardised specification of Markdown. CommonMark is a precise, unambiguous specification created to standardise Markdown behaviour across tools.
Who created the original Markdown?
- The CommonMark working group
- GitHub
- John Gruber (with Aaron Swartz)
- The W3C
Answer: John Gruber (with Aaron Swartz). John Gruber introduced Markdown in 2004, with input from Aaron Swartz; the original spec was loosely defined.
Which features are added by GitHub Flavored Markdown (GFM)?
- Only headings and bold
- Tables, task lists, strikethrough, and autolinks
- YAML front matter parsing
- PDF export
Answer: Tables, task lists, strikethrough, and autolinks. GFM extends CommonMark with tables, task lists, strikethrough, autolinked URLs, and more.
GitHub Flavored Markdown is defined as a strict superset of which spec?
- AsciiDoc
- MultiMarkdown
- The original Gruber Markdown only
- CommonMark
Answer: CommonMark. GFM is formally specified as a superset of CommonMark, adding extensions on top of it.
How is strikethrough written in GFM?
- Double tildes around the text
- Double carets
- Double underscores
- Double slashes
Answer: Double tildes around the text. GFM uses a pair of tildes on each side to strike through text; this is not in the original Markdown.
Why do Markdown flavors differ at all?
- The original spec was vague, so tools added their own extensions
- There is a single legally enforced standard
- Browsers each invented one
- They do not actually differ
Answer: There is a single legally enforced standard. Gruber's original description left edge cases undefined, so implementations diverged and added features independently.
Which of these is known for very broad, configurable Markdown conversion across many output formats?
- A web browser
- A YAML linter
- A text editor's spellchecker
- Pandoc
Answer: Pandoc. Pandoc is a document converter with its own extended Markdown and support for many input and output formats.
Which feature is part of GFM but NOT guaranteed in plain CommonMark?
- Headings with #
- Fenced code blocks
- Task list checkboxes
- Emphasis with *
Answer: Task list checkboxes. Task list checkboxes are a GFM extension; CommonMark defines headings, fenced code, and emphasis but not task lists.
What is the safest way to write Markdown that works everywhere?
- Use every advanced extension you can
- Stick to core CommonMark features and avoid flavor-specific syntax
- Only use raw HTML
- Avoid headings entirely
Answer: Stick to core CommonMark features and avoid flavor-specific syntax. Portable Markdown leans on the common core (headings, lists, links, emphasis) and avoids flavor-specific extensions.
MultiMarkdown is best described as which of the following?
- A Markdown variant adding footnotes, tables, and metadata
- A replacement for HTML
- A GitHub-only mode
- A binary file format
Answer: A Markdown variant adding footnotes, tables, and metadata. MultiMarkdown extends Markdown with features like footnotes, tables, citations, and metadata blocks.
Continue this course
- Previous: Math with LaTeX
- Next: Publishing with MkDocs, Hugo and Jekyll — Turn Markdown into documentation sites and blogs with static site generators
- Quick reference: Markdown cheat sheet