Markdown to Slack: Why Your Bold Text Breaks in the Channel
Slack speaks mrkdwn, not Markdown. Learn the real differences in bold, italic, links, and headings, and how to convert Markdown to Slack so it renders right.
Markdown to Slack: Why Your Bold Text Breaks in the Channel
You write a clean release note in Markdown, paste it into a Slack channel, and the message comes out wrong. The bold version numbers show up with literal double stars wrapped around them. The links read as [Ship v2.3](https://...) instead of clickable words. The section title still has a ## glued to the front. Everyone in the channel sees the raw markup, and you quietly edit the message three times trying to fix it by hand.
This is not a bug in your Markdown. Slack simply does not render standard Markdown. It uses a near-twin dialect called mrkdwn, and the differences land exactly where you paste text from somewhere else. This post walks through what actually changes between the two, with a worked example, so you stop fighting your message box.
Markdown and mrkdwn Are Not the Same Language
Slack's mrkdwn predates Markdown becoming the universal default for plain-text formatting. Slack kept its own syntax for backward compatibility across every desktop, web, and mobile client, so the two grammars look alike but diverge in the details. The result is a set of small mismatches that each break a specific piece of your message.
A message that came from a GitHub comment, a Notion doc, or an LLM answer is written in standard Markdown. Slack reads it as mrkdwn. Where the two agree, it renders fine. Where they disagree, you get literal symbols.
The One Rule That Trips Everyone: Bold Is a Single Asterisk
Here is the single most important difference, and the one that breaks the most copy-paste. In Markdown, bold is wrapped in two asterisks: **shipped**. In Slack mrkdwn, bold is wrapped in one asterisk: *shipped*.
So when you paste a Markdown line straight into a channel, Slack does not see bold. It sees a word with two stuck-on asterisks on each side and prints them as plain text. The word never goes bold. People assume Slack is broken or that their formatting did not "take," when really the markup is one asterisk too many.
The flip side is just as confusing: a single asterisk that means italic in Markdown means bold in Slack. So *emphasis* written for Markdown becomes accidental bold in Slack. Slack italic is underscores instead: _emphasis_. A converter has to handle both directions carefully so a double-asterisk bold never collides with single-asterisk italic mid-rewrite.
A Worked Example
Take a short changelog snippet written in normal Markdown:
## Release 2.3
We **shipped** the new exporter and *deprecated* the old one.
See the [migration guide](https://toolora.com/guide) and ~~rollback notes~~.
Run it through the Markdown to Slack converter and you get mrkdwn that Slack actually renders:
*Release 2.3*
We *shipped* the new exporter and _deprecated_ the old one.
See the <https://toolora.com/guide|migration guide> and ~rollback notes~.
Look at each line. The ## Release 2.3 heading became a bold line, because Slack messages have no heading sizes at all. The **shipped** bold dropped to a single asterisk *shipped*. The *deprecated* italic switched to underscores _deprecated_. The [migration guide](url) link flipped to the angle-bracket form <url|text>. And the ~~rollback notes~~ strikethrough lost one tilde to become ~rollback notes~. Five tokens, five different rules, all in three lines.
Links Reverse Their Order
Markdown links read text first, then the destination: [text](url). Slack reads the destination first, then a pipe, then the text: <url|text>. So [Toolora](https://toolora.com) becomes <https://toolora.com|Toolora> and renders as a clickable word that reads "Toolora."
A bare link with no display text collapses to <https://toolora.com>. And because Slack messages have no inline image markup, an image like  falls back to a plain link <url|diagram>, which is the closest faithful equivalent the channel can show.
Headings, Lists, and Code
Slack message text has no # heading levels. The most faithful equivalent is to bold the whole line, so ## Section becomes *Section* on its own line and keeps the visual hierarchy without leaving a stray hash. Bullet lists convert their - or * markers into Slack's • rows.
Code is the one place the two grammars agree. Inline code stays in single backticks, so ` npm run build passes through untouched. Fenced code blocks keep the triple-backtick fence, though Slack ignores the language tag, so a `` `js `` fence becomes a plain `` ` ```. Anything inside a code block is left verbatim, which matters: an asterisk or hash inside a code sample is never mistaken for formatting.
My Own Reason for Building This
I built this converter after pasting one too many botched announcements into a release channel in front of forty people. The pattern was always the same: I would write the note in a Markdown editor, paste it into Slack, watch the bold version numbers come out as **v2.3**, and then spend a minute deleting one asterisk from each side by hand while the message sat there looking unfinished. After the third time in a week, I decided I would rather paste Markdown into a box once and get mrkdwn back than memorize a translation table I only need under pressure. The converter does the swap live, so by the time I switch to Slack the text is already correct.
Posting to Slack and Bots
For day-to-day messages, the workflow is paste on the left, copy the mrkdwn, paste into the channel. For bots and apps, the mrkdwn output also drops straight into a Slack message payload — set "type": "mrkdwn" on a text block and the single-asterisk bold, underscore italic, and <url|text> links all render the same way they do in the composer. That makes the converter handy for drafting the static parts of a bot message before you wire up the dynamic fields.
Where It Runs
Everything happens in your browser tab. Each regular expression that turns **bold** into *bold* or a [text](url) link into <url|text> runs locally, so the Markdown you paste and the mrkdwn it produces never leave your device. That means an internal announcement, a private channel draft, or a message naming a real customer is safe to convert — nothing is uploaded or logged.
If your destination is a tracker rather than a chat channel, the same idea applies with a different output dialect: see Markdown to Jira, which handles Jira's own wiki markup the same way this tool handles Slack mrkdwn.
The takeaway is simple. Slack is not Markdown. Bold is one asterisk, italic is underscores, strikethrough is one tilde, links put the URL first, and headings become bold lines. Convert once and your channel reads the way you wrote it.
Made by Toolora · Updated 2026-06-13