How to add emoji to Markdown
Try it — edit the markdown and watch the preview
Result
Emoji in Markdown are not really a Markdown feature. A document is text, an emoji is a character, and pasting 🎉 into a file works everywhere by definition. What renderers added on top is a way to name the character instead of typing it — a shortcode.
The two ways, and when each is right
Shortcode: Shipped it :rocket:
Character: Shipped it 🚀
Both render identically here. The differences show up elsewhere:
Shortcode :rocket: | Character 🚀 | |
|---|---|---|
| Typing it | Easy, from the keyboard | Needs a picker, or copy and paste |
| Finding it later | Searchable as rocket | Searchable only as the emoji |
| A renderer that does not support it | Shows :rocket: | Shows 🚀 |
| In a code block | Stays literal | Stays literal |
| Reading the raw file | Says what it is | Depends on your editor’s font |
The short version: use a shortcode when the file lives on GitHub, because that is where they came from and where everyone reading the source will recognise them. Use the character when the file has to travel, because it cannot fail.
The ones a README actually uses
Of about 1,900 shortcodes, a documentation file realistically uses a dozen:
| Shortcode | For | |
|---|---|---|
:white_check_mark: | ✅ | Done, supported, passing |
:x: | ❌ | Not done, unsupported |
:warning: | ⚠️ | A caveat that costs money or data |
:construction: | 🚧 | In progress, unstable |
:bug: | 🐛 | A known problem |
:books: | 📚 | Documentation, further reading |
:bulb: | 💡 | A tip |
:lock: | 🔒 | Security |
:rocket: | 🚀 | Release, deploy |
:sparkles: | ✨ | New feature |
:+1: :-1: | 👍 👎 | Agreement, in a comment thread |
A support matrix with ✅ and ❌ is the one place emoji genuinely beat words: the column scans in a glance, and no wording is shorter than a tick.
Restraint, and the accessibility part
The case against emoji in documentation is not taste, it is that a screen reader
reads them. 🎉 Getting started 🎉 is announced as “party popper Getting started
party popper”, in the middle of navigating a page by headings. One emoji doing a
job — a warning above a caveat — is worth that. Two per heading, as decoration,
is not.
Two practical rules that follow:
- Never let an emoji be the only carrier of meaning. ✅ next to “supported” is fine; a column of bare ✅ and ❌ with no header saying what they mean is a puzzle.
- Keep them out of headings if you can, or accept that the generated
heading id will usually drop the emoji, so
#-getting-startedis not the anchor you get.
Where shortcodes work
| Where | Shortcodes | The character |
|---|---|---|
| Here | Yes | Yes |
| GitHub, GitLab | Yes | Yes |
| Slack, Discord | Yes, with their own lists | Yes |
| Notion | Yes | Yes |
| Obsidian | With a plugin | Yes |
| A strict CommonMark parser | No | Yes |
| A plain text editor | No | Yes, if the font has it |
Note the last column. The character always works. That is the whole argument for it, and it is a strong one for anything you are not sure about.
Common questions
- How do I add an emoji in Markdown?
- Two ways. Type or paste the character itself — 🎉 — which works in every renderer because it is just text. Or write a shortcode, a name between colons like :tada:, which renderers that support them turn into the character. The shortcode is easier to type and easier to search for later; the character is more portable.
- Are emoji shortcodes part of standard Markdown?
- No. Neither CommonMark nor the GitHub Flavored Markdown specification mentions them — they are a GitHub feature that other tools copied. GitHub, GitLab, Slack, Discord, Notion and this editor all understand them. Somewhere that does not, :tada: appears as literal text with the colons showing.
- Where do I find the list of shortcode names?
- There are around 1,900 of them and they follow the Unicode names fairly closely, so guessing usually works: :rocket:, :warning:, :books:, :heavy_check_mark:. The demo above is a live editor, so trying one is faster than looking it up — a name that is not recognised simply stays as written.
- Will a colon in my text turn into an emoji by accident?
- Almost never. A shortcode has to be a known name with a colon at each end, so "10:30:" and a Python slice like a[1:2:3] pass through untouched. Anything not in the list is left exactly as you typed it, which is the same behaviour GitHub has.
- Should I use emoji in documentation at all?
- Sparingly, and with a job to do. A checkmark beside a completed item or a warning triangle above a caveat adds a scannable signal. A decorative emoji in every heading adds noise, and it is read aloud in full by a screen reader — "party popper" in the middle of a sentence is a genuine cost to somebody.
- Do emoji work in file names, headings and links?
- In headings and link text, yes. In file names, technically yes and practically no — some tools, older filesystems and command-line workflows handle them badly. In an anchor, be aware the generated heading id usually drops the emoji, so a link to that heading needs the id rather than the visible text.