Markdown flavors compared: CommonMark, GFM, Discord, Slack, Obsidian, Notion, Reddit, Jira, MDX, Pandoc, reStructuredText
Updated
"Markdown" is a family, not one language. CommonMark is the base spec, GFM is the superset almost everything renders, and each chat app, note app and converter bends the rules — Slack bolds with single asterisks, Discord underlines with double underscores, Notion turns > into a toggle, Reddit hides text with >!…!<. The matrix below puts 22 elements against 11 flavors; the second table says what to write when a document must survive all of them.
Feature × flavor matrix
Each cell is the syntax that platform accepts; "—" means there is no way to write the element. Column headers link to the per-platform sheet; sources are listed under the table.
| Element | CommonMark | GFM | Discord | Slack | Obsidian | Notion | Jira Cloud | MDX | Pandoc | reStructuredText | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Bold | **b** | **b** | **b** | *b* | **b** | **b** | **b** | **b** | **b** | **b** | **b** |
| Italic | *i* _i_ | *i* _i_ | *i* _i_ | _i_ | *i* _i_ | *i* | *i* _i_ | *i* _i_ | *i* _i_ | *i* _i_ | *i* |
| Underline | — | <ins> | __u__ | — | <u> | Cmd+U | — | toolbar | <u> | [u]{.underline} | — |
| Strikethrough | — | ~~s~~ ~s~ | ~~s~~ | ~s~ | ~~s~~ | ~s~ | ~~s~~ | ~~s~~ | ~~s~~ (gfm) | ~~s~~ | — |
| Heading | # … ###### | # … ###### | # ## ### | — | # … ###### | # ## ### | # … ###### | # … ###### | # … ###### | # … ###### | Title
===== |
| Bulleted list | - item | - item | - item | — (type •) | - item | - item | - item | - item | - item | - item | - item |
| Numbered list | 1. item | 1. item | 1. item | — | 1. item | 1. item | 1. item | 1. item | 1. item | 1. item (@) | 1. item #. |
| Task list | — | - [ ] | — | — | - [ ] - [?] | [] +space | — | [] +space | - [ ] (gfm) | - [ ] | — |
| Link | [t](url) | [t](url) | [t](url) | <url|t> | [[Note]] [t](url) | paste URL | [t](url) | [t](url) | [t](url) | [t](url) | `t <url>`_ |
| Bare URL autolink | <url> only | yes | yes | yes | yes | yes | yes | yes | — | with ext. | yes |
| Image |  |  | — | — | ![[img|100]] | /image | — |  |  |  | .. image:: |
| Inline code | `c` | `c` | `c` | `c` | `c` | `c` | `c` | `c` | `c` | `c` | ``c`` |
| Code block | ``` or indent | ```lang | ```lang | ``` | ```lang | /code | ``` (new) indent (old) | ``` | ``` only | ```lang | :: |
| Blockquote | > q | > q | > q >>> all | > q | > q | " (> = toggle) | > q | > q | > q | > q | indent |
| Table | — | | a | b | | — | — | | a | b | | paste / /table | | a | b | | toolbar | | a | b | (gfm) | pipe grid simple multiline | grid / simple |
| Horizontal rule | --- | --- | — | — | --- | --- | --- | --- *** | --- | --- | ---- |
| Footnote | — | [^1] (github.com) | — | — | [^1] ^[inline] | — | — | — | [^1] (gfm) | [^1] ^[inline] | [#]_ |
| Spoiler | — | <details> | ||s|| | — | — | toggle | >!s!< | — | <details> | — | — |
| Callout / alert | — | > [!NOTE] (5) | — | — | > [!tip]- (13) | /callout | — | toolbar panel | <Component> | ::: {.class} | .. note:: |
| Math | — | $x$ $$ (github.com) | — | — | $x$ $$ | /equation | — | — | remark-math | $x$ $$ | :math:`x` |
| Raw HTML | yes | yes, filtered | — | — | yes | — | entities only | — | JSX instead | yes | .. raw:: html |
| Escape character | \ | \ | \ | < > & | \ | — | \ | — | \ (also \< \{) | \ | \ |
- CommonMark: CommonMark spec
- GFM: GFM spec
- Discord: Discord Markdown Text 101
- Slack: Slack mrkdwn reference
- Obsidian: Obsidian Help
- Notion: Notion Markdown shortcuts
- Reddit: Reddit Formatting Guide
- Jira Cloud: Jira markdown shortcuts
- MDX: What is MDX?
- Pandoc: Pandoc's Markdown
- reStructuredText: reST quick reference
Write for maximum portability
The subset that renders identically on GitHub, GitLab, Obsidian, Reddit, Jira, MDX, Pandoc, VS Code and on Notion paste. Chat apps still need their own markers.
| Element | Write | Avoid | Why |
|---|---|---|---|
| Bold | **text** | __text__ | Double underscore is underline on Discord |
| Italic | *text* | _text_ mid-word | Underscores inside words do not trigger emphasis in GFM; Slack needs _ but is a different dialect anyway |
| Strikethrough | ~~text~~ | ~text~ | Single tilde only works in GFM, Slack, Notion and WhatsApp |
| Headings | # … ###, one H1 | #### and deeper, Setext === | Discord and Notion stop at H3 |
| Lists | - item, 1. item, 2-space indent | * and + bullets, 1) numbers | Mixed markers start new lists; 1) fails on old Reddit |
| Links | [text](https://full.url) | bare www. URLs, <url|text> | www. without scheme is not a link on Reddit; CommonMark does not autolink at all |
| Code | ```lang fences | 4-space indented code | Indented code is not supported in MDX; fences are everywhere except old Reddit |
| Line break | blank line = paragraph; two trailing spaces = break | backslash breaks | Backslash works in GFM and new Reddit only |
| Tables | pipe table with outer pipes and a --- row | grid tables, cells with line breaks | Only pipe tables are shared by GFM, Obsidian, Reddit, Pandoc and Notion paste |
| Quotes | > on every line | lazy continuation lines | Chat apps break the quote at the first unprefixed line |
| Callouts | > **Note:** text | > [!NOTE], > [!tip]- | Alert syntax only renders on github.com, GitLab and Obsidian; everywhere else the bracket shows |
| Images |  | ![[wikilink]], relative paths | Wikilinks are Obsidian-only; relative paths break on paste |
| Comments | <!-- --> | %% %% | Obsidian-only; MDX needs {/* */} |
| Emoji | the Unicode character | :shortcode: | Shortcodes expand on GitHub, Slack, Discord, Jira — not in CommonMark renderers |
| HTML | none | <details>, <sub>, <kbd> | Chat apps, Notion and Reddit strip tags; MDX parses them as JSX |
Which flavor am I in?
Match what you saw to the dialect that does it.
| What happened | You are writing |
|---|---|
| *single asterisks* are bold and [text](url) shows the brackets | Slack mrkdwn |
| __double underscore__ underlines, ||bars|| hide text, -# makes small text | Discord |
| [[double brackets]] link notes and ==equals== highlight | Obsidian (or another wiki-style note app) |
| > made a collapsible toggle instead of a quote | Notion |
| >!text!< hides spoilers and ^word floats up | |
| > [!NOTE] rendered as a coloured box; #26 became a link | GitHub (GFM + github.com extras) |
| *bold* with single asterisks, h1. headings, {code} blocks | Jira wiki markup (legacy), not markdown |
| import statements at the top and <Components /> in the body | MDX |
| ::: fenced divs, [@citations], ^superscript^ with carets | Pandoc markdown |
| Titles underlined with ===, ``double backticks`` for code, .. note:: directives | reStructuredText, not markdown |
| Characters like . ! - must be escaped as \. \! \- | Telegram MarkdownV2 (Bot API) |
| Only *bold* _italic_ ~strike~ and ```mono``` work |
The same paragraph in five dialects
Bold, italic, strikethrough, a link and a code span — written for five platforms. The preview on the right is how a GFM renderer (this site, GitHub) reads each one.
CommonMark / GFM / Obsidian / Reddit / Jira
**bold** *italic* ~~struck~~ [docs](https://docs-md.com) `code`bold italic struck docs code
The widest overlap. CommonMark alone lacks ~~strikethrough~~; everything else here is in all five.
Slack mrkdwn
*bold* _italic_ ~struck~ <https://docs-md.com|docs> `code`bold italic struck docs code
Single markers and <url|text> links. Pasted into GitHub, *bold* becomes italic and the link shows its angle brackets.
Discord
**bold** *italic* ~~struck~~ __underlined__ ||spoiler|| [docs](https://docs-md.com) `code`bold italic struck underlined ▮▮▮▮▮▮▮ docs code
__double underscore__ is underline, not bold; ||spoiler|| is Discord-only. Masked links render in messages; wrap a URL in < > to suppress its embed.
Telegram MarkdownV2
*bold* _italic_ ~struck~ __underlined__ ||spoiler|| [docs](https://docs-md.com) `code`\. Escape \- \! \. outside entities\.Single markers like Slack, plus __underline__ and ||spoiler|| like Discord — and every one of _ * [ ] ( ) ~ ` > # + - = | { } . ! must be backslash-escaped in plain text.
*bold* _italic_ ~struck~ ```monospace``` `inline code`
> quote
- bullet
1. numberedbold italic struck monospace inline code
quote
- bullet
- numbered
Single markers; no headings, links are plain URLs, no tables. Three backticks make inline monospace, not a block.
reStructuredText vs Markdown
reST (Sphinx, Python docs) is a different language with the same goals: readable plain text that compiles to HTML. The markers overlap just enough to be confusing.
The same section in reST
Install
=======
Run ``pip install docs`` then see `the guide <https://docs-md.com>`_.
.. note::
Directives replace markdown's HTML escape hatch.
- *emphasis* and **strong** match markdown
- literal blocks follow a paragraph ending in ::
::
indented codeInline code needs two backticks, links are `text <url>`_, headings are underlined with any punctuation character, and tables are drawn with + - | or = rows. Convert between the two with Pandoc (-f rst -t gfm).
Per-platform cheat sheets
- Markdown cheat sheetThe CommonMark + GFM core, every element rendered.
- GitHub Flavored MarkdownTables, task lists, alerts, footnotes, math, mermaid.
- ObsidianWikilinks, embeds, 13 callout types, properties, tags.
- NotionTyping shortcuts, what imports, what export produces.
- RedditSpoilers, superscript, tables, old vs new Reddit.
- DiscordUnderline, spoilers, subtext, headers, no tables.
- Slackmrkdwn: single asterisks, <url|text> links.
- TelegramMarkdownV2 and its escaping rules.
- WhatsAppBold, italic, strikethrough, monospace, lists, quotes.
- JiraMarkdown shortcuts vs legacy wiki markup.
- MDXComponents, expressions and imports in markdown.
- PandocDivs, spans, citations, four table styles.
- Markdown for AI outputWhat ChatGPT, Claude and Gemini render.
What is the difference between CommonMark and GFM?
CommonMark is the unambiguous base specification of markdown: headings, emphasis, lists, links, images, code, blockquotes, raw HTML. GitHub Flavored Markdown is a strict superset that adds five extensions — tables, task lists, strikethrough, bare-URL autolinks and an HTML tag filter — and github.com adds alerts, footnotes, math, mermaid, emoji shortcodes and references on top. Anything valid in CommonMark renders the same in GFM.
Which markdown flavor should I write in?
GFM, unless you are targeting one specific app. It is the default of GitHub, GitLab, VS Code preview, most static site generators, remark/markdown-it, Obsidian's shared subset and every AI assistant's output. For chat apps (Slack, Discord, Telegram, WhatsApp) write in their dialect at send time rather than pasting GFM.
Is Slack markdown?
No. Slack calls its format mrkdwn and documents it as "inspired by markdown, but uses different rules": *single asterisks* are bold, _underscores_ italic, ~tildes~ strikethrough, links are <url|text>, and there are no headings, tables, images or list syntax. Pasting GFM into Slack produces visible asterisks and brackets.
What is the difference between reStructuredText and Markdown?
Both are plain-text markup, but reST is a single formal spec (docutils) with an extensible directive system (.. note::, .. image::, .. toctree::) and roles (:math:`x`), while markdown is a family of dialects with raw HTML as the escape hatch. reST uses ``double backticks`` for code, `text <url>`_ for links and underlined titles; it has no bold-italic, no task lists and no pipe tables. Sphinx and Python documentation use reST; almost everything else uses markdown. Pandoc converts between them.
Why does my markdown look different on Discord, Slack, Notion and Reddit?
Because each one implements its own parser with its own rules. Discord treats __ as underline and has no tables or images; Slack uses single-character markers and ignores [text](url); Notion converts > into a toggle while typing and has only three heading levels; Reddit adds >!spoilers!< and ^superscript and, on old Reddit, lacks fenced code. The matrix above shows the exact syntax per element so you can rewrite before pasting.
What is the most portable markdown?
The CommonMark core written in its most common form: **bold**, *italic*, # headings up to H3, - bullets, 1. numbers, [text](https://url), ```fenced code, > quotes with every line prefixed, blank lines between blocks, and pipe tables when you need them. Skip HTML, shortcodes, alerts, footnotes and anything with a platform name in this matrix. The portability table lists the swaps.
Are MDX and Pandoc markdown separate flavors?
Yes, in opposite directions. MDX is markdown (CommonMark + GFM via plugins) that also parses JSX, import/export and {expressions}; it drops indented code, autolinks and raw HTML in exchange. Pandoc's markdown is the broadest superset — fenced divs, bracketed spans, four table styles, citations, definition and example lists, inline footnotes, ^super^ and ~sub~ — meant for converting to LaTeX, DOCX and HTML rather than for rendering in an app.
Tools
Check how GFM renders a document in the markdown viewer, normalise markers with the formatter, find flavor-specific syntax with markdown lint, convert to HTML or Word, or share markdown as a rendered link instead of pasting it into a chat app.