Slack Markdown Formatting
Slack uses its own Markdown variant called mrkdwn. Single asterisks for bold, angle-bracket links, and no native lists or headers. Here is every difference, with copy-ready examples.
The Slack composer is forgiving and accepts standard Markdown shortcuts. The API and Block Kit are strict — they only accept mrkdwn.
Read this first
Three things Slack does differently from every other Markdown
1. Bold
*bold* not **bold**
A single asterisk wraps bold text. Double asterisks render as literal text.
2. Strikethrough
~strike~ not ~~strike~~
One tilde on each side. The GitHub-style double tilde does not work.
3. Links
<url|text> not [text](url)
Angle brackets and a pipe. The standard Markdown link works only in the composer.
Text Formatting
Slack's emphasis syntax differs from standard Markdown. Most other tools render the syntax below incorrectly, so the "How it looks in Slack" panel shows the actual Slack rendering.
Slack uses *one* asterisk for bold. **Two** asterisks render as literal text with asterisks visible.
*bold text*Underscores around the text. Asterisks around text mean bold in Slack, not italic.
_italic text_Slack uses one tilde on each side. Two tildes (~~text~~) is GitHub style and does not work.
~strikethrough~Nest underscores inside asterisks (or vice versa). Slack has no triple-asterisk shortcut.
*_bold italic_*Links
Slack's mrkdwn uses angle brackets and a pipe to mask links — not the[text](url)syntax. If you are typing in the composer, the standard shortcut works and is converted on send. But API messages and Block Kit text fields require the angle-bracket form.
Use angle brackets and a pipe. This is the format the Slack API expects when sending messages with mrkdwn: true.
<https://slack.com|Slack>A bare URL in angle brackets shows the URL as the link text.
<https://slack.com>When typing in Slack's message composer, the standard Markdown link shortcut is converted on the fly. It does NOT work in API messages or Block Kit mrkdwn fields.
[Slack](https://slack.com)<https://example.com|click here>. Slack will display only the text, with the URL accessible on hover.Mentions
Slack mentions use angle brackets and IDs, not display names. The composer auto-completes @username into the proper ID, but API messages must already contain the ID.
Use the user ID, not the display name. The Slack client renders it as @username.
<@U024BE7LH>Channel ID with the channel name after a pipe. Slack renders it as #general.
<#C024BE7LV|general>Pings everyone in the channel. Use sparingly — many workspaces restrict this.
<!channel>Only pings members currently active in the channel. Less disruptive than @channel.
<!here>User-group ID with a fallback display name. Renders as @team-name.
<!subteam^S0NHM1FH4|team-name>Lists
This is where Slack gets weird. Mrkdwn does not support lists. If you type - item in the composer, Slack creates a rich-text list block — but that is a Block Kit feature, not mrkdwn. API messages with mrkdwn cannot produce bulleted or numbered lists.
In the composer
Type - item or 1. item and Slack converts it to a rich-text list block as you type. Press Enter to add another item.
- First item
- Second item
- Third item
In API messages (mrkdwn)
Sending { mrkdwn: true, text: "- one\n- two" } renders the hyphens as literal characters. To get a real list, use a Block Kit rich_text block with rich_text_list elements.
- one - two
Headers
Mrkdwn has no heading syntax. The composer accepts a # heading shortcut and inserts a Block Kit header block, but this is a UI feature, not part of the mrkdwn format itself.
Use a Block Kit header block instead of mrkdwn. Header blocks are a structural element separate from text content:
{
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "Section Title" }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "Body copy with *bold* text." }
}
]
}Blockquotes
Blockquotes work the same as standard Markdown. Start a line with > to indent and quote it. Slack does not support a triple-bracket >>> for multi-line quotes the way Discord does — repeat > on each line.
> Single-line blockquote in Slack.Single-line blockquote in Slack.
> Line one of a multi-line quote.
> Line two continues here.Line one of a multi-line quote.
Line two continues here.
Code
Inline code and fenced code blocks work the same as CommonMark. Slack uses a monospace font and preserves whitespace, but does not apply syntax highlighting — a language identifier on the opening fence is silently ignored.
`inline code`inline code
```
function hello() {
return "world";
}
```function hello() {
return "world";
}
Composer vs API mrkdwn
The single biggest source of confusion is that Slack's composer (the input box) and the underlying mrkdwn format accept different syntax. The composer is forgiving — it converts standard Markdown shortcuts on send. The API is strict and only accepts mrkdwn.
| Feature | Composer accepts | API / mrkdwn requires |
|---|---|---|
| Bold | **text** or Cmd/Ctrl+B | *text* |
| Italic | *text* or Cmd/Ctrl+I | _text_ |
| Strikethrough | ~~text~~ or Cmd/Shift+X | ~text~ |
| Inline code | `code` | `code` |
| Code block | ```code``` or Cmd/Shift+C | ```code``` |
| Link | [text](url) | <url|text> |
| Bulleted list | - item (creates rich_text_list block) | Not supported in mrkdwn |
| Numbered list | 1. item (creates rich_text_list block) | Not supported in mrkdwn |
| Heading | # heading (creates header block) | Not supported in mrkdwn |
| Quote | > quote | > quote |
Common Mistakes
The most frequent ways people get Slack mrkdwn wrong. Each row shows what does not work and the correct mrkdwn version.
Does not work
**bold**Use instead
*bold*Does not work
~~strikethrough~~Use instead
~strikethrough~Does not work
[click here](https://example.com)Use instead
<https://example.com|click here>Does not work
@aliceUse instead
<@U024BE7LH>Does not work
```python
code
```Use instead
```
code
```Quick Reference
Every Slack mrkdwn syntax and feature support at a glance.
| Syntax / Feature | Works in Slack? | Notes |
|---|---|---|
| *bold* with single asterisks | Yes | Native — but breaks if you paste from CommonMark. |
| **bold** with double asterisks | No | Renders as literal **text** in mrkdwn. Composer converts on send. |
| _italic_ with underscores | Yes | Native syntax. |
| ~strikethrough~ (single tilde) | Yes | Native syntax. |
| ~~strikethrough~~ (double tilde) | No | Not recognized. Composer accepts the shortcut and converts. |
| [text](url) link syntax | Partial | Composer converts to <url|text> on send. API messages must use angle brackets. |
| <url|text> link syntax | Yes | The canonical mrkdwn form. |
| # Headings | Partial | Composer creates a separate header block. Raw mrkdwn renders # as literal text. |
| - and 1. lists | Partial | Composer creates rich_text_list blocks. Raw mrkdwn does not render bullets. |
| > Blockquotes | Yes | Same as CommonMark. |
| ``` code blocks ``` | Yes | Triple backticks. Language identifier is ignored — no syntax highlighting. |
| Tables | No | Not supported. Paste as a code block to keep alignment. |
| Images via  | No | Use the file upload UI, or use the image block in Block Kit. |
| @username mention | Yes | Use <@USER_ID> format in API messages; composer auto-formats. |
| :smile: emoji shortcodes | Yes | Slack expands shortcodes inline. |
Frequently Asked Questions
Why does *text* show as bold in Slack but italic everywhere else?
Slack invented its own markdown variant called mrkdwn before CommonMark stabilized. In CommonMark, single asterisks mean italic and double asterisks mean bold. Slack flipped that: a single asterisk means bold, and underscores mean italic. This is the single biggest source of confusion when copy-pasting between GitHub, Discord, and Slack.
What is the difference between Slack's composer and mrkdwn?
The composer is the input box where you type messages. It is WYSIWYG and accepts standard Markdown shortcuts like **bold** and [text](url) that it converts on send. Mrkdwn is Slack's stored message format — the API and Block Kit text fields expect mrkdwn-native syntax: *bold*, _italic_, <url|text>. If you build a bot or send messages via the API, you must use mrkdwn directly.
Does Slack support markdown headings?
Not in raw mrkdwn. The # character renders as literal text. The composer accepts the # shortcut and creates a separate Block Kit header block, but this is a UI affordance, not a mrkdwn feature. If you are sending messages via the API, use a Block Kit header block instead.
Why don't my bullet lists work in Slack messages from the API?
Lists are not part of mrkdwn. The composer creates rich_text_list blocks when you type - or 1. — these are stored as Block Kit blocks, not mrkdwn. To send a bulleted list via the API, use the rich_text block with rich_text_list elements, not mrkdwn formatting.
How do I link to a URL with custom text in Slack?
Use the format <https://example.com|Click here>. Angle brackets wrap the URL, and a pipe separates the URL from the display text. The standard Markdown [text](url) syntax works in the composer (it converts on send) but not in API messages.
Can I include syntax highlighting in Slack code blocks?
No. Slack code blocks use a monospace font and preserve whitespace, but they do not apply syntax highlighting. You can write ```python at the top of a fence, but Slack ignores the language identifier.
How do I mention a user from a Slack bot or webhook?
Use <@U024BE7LH>, replacing U024BE7LH with the user's Slack ID (not their display name). You can fetch user IDs from the users.list API. The same pattern applies to channels (<#C024BE7LV|channel-name>) and user groups (<!subteam^S0NHM1FH4|team-name>).
Are Slack tables supported?
No. Slack does not support Markdown tables — no |---| header separator syntax. The most common workaround is to format tabular data inside a code block, using spaces to align columns. The fixed-width font preserves alignment.
How do I escape special characters in Slack API messages?
Slack interprets <, >, and & specially when parsing mrkdwn. Replace them with their HTML entities: < for <, > for >, and & for &. This is only required when sending via the API — the composer handles escaping for you.
Learn More Markdown
Slack's mrkdwn is one of several Markdown variants. Compare it to the standards and other platforms: