Markdown in Slack and Discord: Why Your Formatting Doesn't Match
Paste a Markdown snippet into Slack and the bold text shows up as literal asterisks. Paste that same file into Discord and it mostly works — until you try a heading, and nothing happens. Neither app is broken. Slack and Discord each run their own dialect of Markdown, and once you know where the mismatches come from, they're easy to predict.
Why "Markdown" Isn't One Spec
There's no single, universally enforced Markdown standard. CommonMark comes closest to a formal spec — it defines **bold**, *italic*, and [text](url) links precisely enough for other parsers to converge on. GitHub Flavored Markdown (GFM) builds on that with extras like task lists and ~~strikethrough~~, and it's the dialect most people mean by "standard Markdown" today.
Chat platforms don't implement either one strictly. They borrow syntax where it's convenient and invent their own where it isn't. It's the same underlying problem behind why the same Markdown file can render differently depending on the parser — just more visible here, because you're pasting the same text into several tools in one afternoon.
Bold and Italic: Slack's Inverted Asterisk Convention
Classic mrkdwn — the format used in regular chat messages and most Block Kit block types — flips the CommonMark convention entirely. A single asterisk, *text*, renders bold in Slack. In CommonMark and GFM, that same syntax means italic. It's the exact inverse, and it's the single most common source of "why doesn't my formatting work" confusion. (See the full rundown of Markdown's emphasis syntax for how bold and italic behave outside chat apps.)
It gets stranger with double asterisks. Text like **bold** sent through the API or Block Kit's classic block types doesn't get parsed as bold. It shows up as two literal asterisk characters, because the API only understands true mrkdwn, not standard Markdown. The composer window is more forgiving — type **text** by hand and its client-side helper auto-converts it, which is exactly why the same string looks fine when you type it and breaks when a script sends it.
There's one exception. Slack shipped a dedicated "markdown" block type in February 2025 that accepts real CommonMark-style Markdown, double-asterisk bold included, so integrations built around standard Markdown don't have to hand-convert into mrkdwn first. If your formatting lands correctly in some Slack integrations and not others, that's usually why: one uses the new markdown block, the other's still on classic mrkdwn.
Links and Headings: What Classic mrkdwn Leaves Out
Links aren't just punctuated differently — they're a different format entirely. Classic mrkdwn skips [text](url) in favor of <url|text>, angle brackets and a pipe instead of brackets and parentheses. That's why pasting a Markdown link into a Slack message field usually just posts the raw brackets and parentheses as text. (For how Markdown links are supposed to work, see inline vs. reference-style links.)
Headings fare worse. None of Markdown's six # levels have any equivalent in classic mrkdwn — paste in notes with ## subheadings and the hash marks just sit there as literal characters. Slack's newer markdown block type does support headings, but per Slack's own reference, every level renders at the same visual size regardless of whether you wrote # or ######. Even the exception doesn't give you a true heading hierarchy.
Discord's Markdown: Underlines and Other Additions
Discord's chat formatting supports standard bold and italic without the inversion problem Slack has, but it adds syntax of its own — most notably underlining, which has no equivalent in CommonMark or GFM. Markdown's creator, John Gruber, has argued that underlining should be reserved for hyperlinks by typographic convention. That makes Discord's addition a deliberate extension, not an attempt at strict compatibility.
Strikethrough tells a similar story. Slack's ~text~ (single tilde) and GFM's ~~text~~ (double tilde) both trace back to GitHub Flavored Markdown, not to any Markdown standard. Gruber never included strikethrough syntax in the original spec at all — tildes look "squiggly" next to an actual strikethrough line, he reasoned, and the feature wasn't common enough to justify the complexity. Every platform picked its own answer to a feature the original spec never defined. "Markdown" isn't one thing you either support or don't; it's a baseline plus whatever each platform bolted on.
Code Blocks: The One Thing That Mostly Survives Copy-Paste
Triple-backtick fences are the exception that actually works consistently. They render as a code block in CommonMark, GFM, classic Slack mrkdwn, and Slack's markdown block type alike — paste a fenced snippet anywhere and the box shows up.
The catch is syntax highlighting. Classic mrkdwn ignores any language identifier after the opening fence — write `javascript and Slack renders a plain monospace block with no highlighting, no matter what language you specified. Keep a snippet library and paste from it into Slack often enough, and you'll learn fast: the code travels, the highlighting doesn't. (More on keeping code snippets in plain Markdown files so they stay portable.)
How Carets Fits In
Carets is a fast, native notes and code editor for iPhone, iPad, and Mac, built around Markdown and plain text with real syntax highlighting for code and config files. Your notes stay in standard Markdown — the CommonMark-adjacent syntax this article describes, not a proprietary format — so you're never translating out of an app-specific dialect before pasting into Slack or Discord in the first place. Code snippets get real syntax highlighting for the language you actually wrote, right in the editor, even though that highlighting won't survive a paste into classic Slack mrkdwn.
Carets is native and fast on iOS and Mac rather than a web wrapper, and it keeps writers and developers in one tool — files, projects, and tags stay organized without a separate app for notes versus code. Get it on the App Store for iPhone, iPad, and Mac.
Frequently Asked Questions
Why does bold text I paste into Slack show up as literal asterisks?
Classic mrkdwn — used in regular chat messages and most Block Kit block types — only recognizes single asterisks (*text*) for bold. Double asterisks (**text**) are standard Markdown/GFM bold syntax, but mrkdwn doesn't parse them as formatting; it shows the asterisk characters literally. The composer UI auto-converts as you type, but anything sent via the API in classic mrkdwn is parsed strictly. Slack's newer "markdown" block type, shipped February 2025, is the exception — it accepts real double-asterisk bold.
Does Slack support Markdown headings?
Not in classic mrkdwn. None of Markdown's six heading levels have any equivalent in Slack's regular chat messages. Paste in notes with headings and the # characters show up as literal text. Slack's newer markdown block type does support headings, but that's a specific Block Kit component, not the format used in ordinary messages.
Why does my code block lose syntax highlighting when I paste it into Slack?
Triple-backtick code fences work the same in Slack as in standard Markdown, but classic mrkdwn ignores any language identifier after the opening fence (like `python ). Slack renders the block in monospace with no highlighting regardless of what language you specify, so highlighting that looked correct in your source file disappears the moment you paste it into a message.
The Takeaway
The mismatch isn't a bug in either platform. "Markdown" is a family of dialects, and Slack in particular runs two of them side by side. Know whether you're targeting classic mrkdwn, Slack's newer markdown block, or Discord's own formatting, and you can write your source once in plain Markdown and adapt the syntax deliberately — instead of guessing why the same paste looked right in one place and wrong in another.