If you’ve ever pasted a chunk of Markdown into Slack expecting headings and tables to show up nicely, you’ve already learned the hard way: Slack doesn’t speak Markdown. It has its own lookalike format called mrkdwn (yes, missing the “a” — that’s the actual name Slack uses in its own API docs), and it diverges from standard Markdown in ways that are easy to get wrong.

This guide covers the full syntax mapping, what Slack simply can’t render, and the gotcha that trips up most people building bots or webhooks: the difference between typing in the Slack message box and sending mrkdwn through the API.

Markdown vs. Slack’s mrkdwn

The two syntaxes look similar at a glance, but several common Markdown conventions use different characters in Slack — and a few have no equivalent at all.

Formatting Markdown Slack mrkdwn
Bold **bold** *bold*
Italic *italic* or _italic_ _italic_
Strikethrough ~~strike~~ ~strike~
Inline code `code` `code` (same)
Code block ```code``` ```code``` (same)
Blockquote > quote > quote (same, one level only)
Link [text](url) <url\|text>
Heading # Heading No native heading — use bold instead
Unordered list - item • item (see notes below)
Ordered list 1. item Not auto-numbered — type numbers manually
Horizontal rule --- Not supported in message text
Table \| a \| b \| Not supported at all
Image ![alt](url) Not supported inline

The single asterisk for bold is the one that catches people most often — it’s the exact opposite of standard Markdown, where a single asterisk means italic. Type *this* in Slack and you’ll get bold, not italics.

The Trap: Typing in Slack vs. Sending via API

Here’s the detail that most guides skip, and the one that matters most if you’re building a bot, webhook, or CI notification: Slack’s message composer and Slack’s API don’t behave identically.

When you type directly into the Slack message box, the client does some helpful auto-formatting as you go — typing - at the start of a line converts it to a bullet, and typing 1. will auto-number subsequent lines while you’re actively editing. This is a composer-only convenience.

When you send text programmatically — via chat.postMessage, an incoming webhook, or a Block Kit mrkdwn text object — none of that auto-formatting happens. A literal - item sent through the API renders as the literal characters - item, not a bullet. If you want real bullets from a bot or script, you need to insert the actual bullet character (, Option+8 on Mac, or the Unicode character U+2022) yourself, or build proper Block Kit list structures. The same applies to numbered lists — the API will not auto-number 1. / 2. / 3. for you.

If your Markdown-to-Slack workflow runs through automation (a Git-to-Slack notifier, a changelog bot, a CI pipeline), test the actual API output, not just what you see typing manually in a channel.

What Doesn’t Convert

Headings

Slack’s mrkdwn has no heading syntax at all — no #, no font-size levels. The only way to get a “heading” look in an ordinary message is to bold the line: *Section Title*. If you’re using Block Kit (Slack’s structured message format for apps and bots), there’s a dedicated header block type, but that’s a separate block, not something you write inline in mrkdwn text.

Tables

There is no table support in Slack messages — not in mrkdwn, and not in standard Block Kit blocks either. If your Markdown source has tables, you have a few options: convert the table to a formatted list, use Block Kit’s fields array in a section block to fake a rough two-column layout, or drop the table and link out to the full document instead. There is no clean equivalent, so if tables matter, don’t rely on message text at all.

Images

![alt](url) doesn’t render inline. Slack ignores the syntax entirely and shows it as literal text. To actually display an image in Slack, you need a separate image block in Block Kit, or you paste the image file itself into the channel. A Markdown image reference converted straight to Slack text will just look broken — most conversion tools (including ours) strip the image markup and keep the alt text so at least the description survives.

Nested Lists

Slack doesn’t have a native concept of list nesting depth in mrkdwn. Manually indenting with spaces before a bullet character will usually render with some visual indentation in the client, but it’s not a documented, reliable feature — behavior has changed across Slack client versions. If nesting matters for readability, consider flattening to a single level with prefixes (Frontend: Component X) rather than depending on indentation.

Horizontal Rules

--- has no special meaning in Slack message text — it renders as three literal dashes. The closest equivalent in Block Kit is the divider block, which is a structural element, not something you can type inline.

Footnotes, Definition Lists, Task Lists

None of these have any Slack equivalent. Footnote references ([^1]) show up as literal bracket text. Task list checkboxes (- [ ]) render as literal text — Slack has no native inline checkbox in message text (interactive checkboxes exist only as Block Kit UI elements requiring an app, not plain-text formatting).

HTML

Slack strips or ignores raw HTML in message text entirely. If your Markdown source has embedded HTML for layout tricks, none of it will survive — plan on it disappearing.

Escaping Characters for API Use

If you’re sending mrkdwn through the API rather than typing manually, three characters need HTML-entity escaping because they have special meaning in Slack’s format (particularly < and >, which wrap links):

Character Escape as
& &amp;
< &lt;
> &gt;

Skip this and a message containing a literal < or > — say, example code like if (x < y) — can get mangled or silently dropped, since Slack tries to parse it as the start of a link tag.

Quick Reference

Markdown feature Slack support What happens
Bold / italic / strikethrough Yes Different characters (see table above)
Inline code / code blocks Yes Same backtick syntax
Blockquote Partial Works, single level only
Links Yes Different syntax: <url\|text>
Headings No Falls back to bold text
Tables No No equivalent, renders as broken text
Images No Ignored inline; needs a separate Block Kit block
Ordered/unordered lists Partial Composer auto-formats; API does not
Nested lists No Unreliable, client-dependent indentation only
Horizontal rule No Renders as literal dashes
Footnotes, definition lists, task lists No No equivalent
HTML No Stripped

Using the Converter

Our Markdown to Slack converter handles the mechanical parts of this conversion automatically:

  • Converts **bold** to *bold* and italics to _italic_
  • Converts ~~strikethrough~~ to ~strikethrough~
  • Converts headings to bold text (since Slack has no heading syntax)
  • Converts [text](url) links to Slack’s <url|text> format
  • Strips image Markdown while keeping the alt text so the description isn’t lost
  • Removes horizontal rules
  • Shows a warning badge if it detects a table in your source, since Slack can’t render it
  • Protects code blocks and inline code from being touched by the other conversions

Paste your Markdown on the left and get Slack-ready mrkdwn on the right, with a side-by-side comparison so you can see exactly what changed. No signup required.

This is especially useful for release notes, changelog summaries, or documentation excerpts you’re pasting into a channel — the kind of content that’s authored in Markdown but consumed in Slack.