How to strip emojis from readme & repo markdown
- Step 1Load the README — Paste the README contents or upload
README.md. The tool handles one file per run. - Step 2Diff with Replace first — Set Mode to Replace with [name] and run, so you can eyeball every former emoji as a bracketed token before committing anything.
- Step 3Keep install commands safe — Leave Process code blocks too unchecked so fenced ``
`` install and usage snippets are preserved exactly. - Step 4Run De-Emoji — Click Run De-Emoji. Check the hero line for a double space where an emoji was removed and confirm no CI/status
:word:token was caught by the shortcode matcher. - Step 5Switch to Strip for the clean README — Once the diff looks right, set Mode to Strip (remove) and run again to delete the emoji and shortcodes for the final file.
- Step 6Copy back into the repo — Use Copy or Download to write the cleaned
README.md. Keep the community version on a separate branch if you maintain both variants.
Every option this tool exposes (and nothing it does not)
The De-Emoji panel has exactly two controls. There is no allow-list, no per-emoji picker, no 'keep meaningful emoji' toggle, and no name dictionary — these are the real defaults from lib/markdown/markdown-tool-schemas.ts.
| Control (UI label) | Field | Values | Default | Effect |
|---|---|---|---|---|
| Mode → Strip (remove) | mode | strip | Yes (default) | Deletes each matched emoji and each :shortcode: outright. Surrounding spaces are left in place — they are not collapsed. |
| Mode → Replace with [name] | mode | replace | — | Wraps each matched emoji in square brackets (the literal glyph stays inside, e.g. the rocket becomes [ rocket-glyph ]) and turns :rocket: into [rocket]. |
| Process code blocks too | includeCodeBlocks | true / false | false (off) | Off: fenced `` `` blocks are skipped so command-line emoji or test fixtures stay intact. On: emoji inside fences are processed identically to prose. |
Before / after by mode (verified output)
Exact transformations produced by the strip and replace passes. Note the leftover space after removal and the bracket-the-glyph behaviour in Replace mode.
| Input fragment | Strip output | Replace output |
|---|---|---|
Ship it (rocket-emoji) today | Ship it today (double space remains) | Ship it [rocket-glyph] today |
Done :white_check_mark: | Done (shortcode removed) | Done [white_check_mark] |
Status: :) | Status: :) (ASCII emoticon untouched) | Status: :) (ASCII emoticon untouched) |
(c) 2026 ACME (tm) | (c) 2026 ACME (tm) (marks survive) | (c) 2026 ACME (tm) (marks survive) |
thumb-emoji + skin-tone | `` (both code points removed) | [thumb-glyph][skin-glyph] (two tokens) |
What counts as an emoji (matched Unicode ranges)
The de-emoji pass matches these Unicode blocks, each optionally followed by the U+FE0F variation selector. Anything outside these blocks is left untouched — verified directly against the matcher in lib/markdown/markdown-processor.ts.
| Block / range | Examples it matches | What it does NOT catch | Why it matters |
|---|---|---|---|
| U+1F600–1F64F (Emoticons) | grinning, wink, crying, neutral faces | ASCII emoticons like :) :-( ^_^ (plain text, never matched) | Face emoji are the most common decorative noise in AI-drafted prose |
| U+1F300–1FAFF (Misc Symbols & Pictographs, Supplemental, Extended-A) | weather, food, animals, hands, objects, newer 2020+ emoji | Letterlike symbols (tm) U+2122, (c) U+00A9, (R) U+00AE | Trademark and copyright marks survive — they are not emoji |
| U+2600–27BF (Misc Symbols + Dingbats) | check mark, star, heart, warning, arrows-as-dingbats | Box-drawing, geometric shapes below U+2600, math operators | A literal check (check) in a feature list is treated as decorative and removed |
| U+1F680–1F6FF (Transport & Map) | rocket, car, plane, warning-triangle transport icons | Map pin variants outside the block | Common in README hero lines and roadmap bullets |
| U+1F900–1F9FF (Supplemental Symbols) | additional hands, gestures, body parts, fantasy | Skin-tone modifier in isolation is matched as its own token | Skin-tone + base render as two bracket tokens in Replace mode |
| U+1F1E6–1F1FF (Regional Indicators) | the two-letter pieces that combine into flags | The flag as a single grapheme is matched as two code points | A flag becomes two bracket tokens in Replace mode, not one |
Cookbook
README fragments before and after. (rocket), (check), (sparkles) stand in for literal emoji glyphs; badge/link syntax is shown literally.
Clean the hero line
The classic emoji-decorated project title. Strip removes the rocket; note the double space it leaves behind.
Mode: Strip Input: # (rocket) MyLib > The fastest widget library (sparkles) Output: # MyLib > The fastest widget library (Double space after the # and trailing space on the tagline.)
Badges and links are preserved
shields.io badges and Markdown links are not emoji. This no-op proves the badge row survives.
Mode: Strip Input:  [Docs](https://example.com) Output:  [Docs](https://example.com) (Image and link syntax untouched.)
Install snippet protected
Fenced install commands must not change. With Process code blocks off, the fence is skipped.
Mode: Strip, Process code blocks: OFF Input: Get started (rocket): ```bash npm install mylib # ready to go (rocket) ``` Output: Get started : ```bash npm install mylib # ready to go (rocket) ``` (Prose stripped; the fenced comment's emoji kept.)
Strip a contributing-section shortcode
GitHub renders :tada: as a glyph; an internal portal may show literal text. Strip removes both.
Mode: Strip Input: Thanks for contributing :tada: First-timers welcome :+1: Output: Thanks for contributing First-timers welcome (Both shortcodes removed; trailing spaces remain.)
Watch a CI status token
If your README references a :status:-style token, the shortcode matcher catches it. Verify before committing.
Mode: Strip Input: Current pipeline: :passing: as of today (check) Output: Current pipeline: as of today (:passing: removed as a shortcode — restore if it was literal text you needed.)
Edge cases and what actually happens
Hero-line strip leaves a double space
By design# (rocket) MyLib becomes # MyLib. Removal does not collapse whitespace. Run the result through md-prettifier or fix the heading by hand before committing.
Badges and links are preserved
Preservedshields.io badges () and Markdown links are not emoji, so the matcher leaves them alone. Your CI/coverage/license badge row survives intact.
Install commands in fences untouched
By designWith 'Process code blocks too' off, fenced install/usage snippets keep any emoji in comments. Enable the option only if you specifically want code comments de-emoji'd too.
License footer marks preserved
Preserved(c), (tm), and (R) in a license or attribution line are outside the matched ranges and pass through unchanged.
CI/status `:word:` token removed
ExpectedThe shortcode matcher catches any lowercase :word:, so a status token like :passing: is removed or bracketed. Use Replace first to spot these and restore any that were literal text.
Flag emoji in an i18n section splits
ExpectedA 'translations' section using country-flag emoji will see each flag treated as two regional-indicator code points: in Replace mode you get two bracket tokens, in Strip mode both are removed. Use plain language names if you want labels.
README over the character limit
LimitMost READMEs are well under the Free 500,000-character cap, but a giant monorepo README plus generated tables could exceed it. Upload the file or split with md-splitter if the Run button is disabled.
Maintaining two README variants
ExpectedThe tool produces one output per run and does not manage branches. If you keep both a community and an enterprise README, store the community version on its own branch and re-run De-Emoji whenever it changes.
Replace keeps the literal glyph in brackets
ExpectedA Unicode rocket becomes [ glyph ], not [rocket]; only :rocket: shortcodes become a word. Treat bracketed Unicode tokens as diff markers, then Strip for the final README.
Frequently asked questions
Will it remove my shields.io badges?
No. Badges use Markdown image syntax , which is not emoji, so the matcher leaves them untouched. Your CI, coverage, and license badges survive.
Are emoji in install snippets removed?
Not by default. Fenced code blocks are skipped unless you check 'Process code blocks too', so npm install and similar commands keep every character, including emoji in comments.
Does Strip remove `:tada:` and `:+1:` shortcodes?
Yes. Strip removes both Unicode emoji and :name: shortcodes. A contributing section full of :tada: and :+1: comes out clean.
Why does my project title have two spaces now?
Stripping # (rocket) MyLib leaves the spaces around the emoji, producing # MyLib. Tidy it with md-prettifier or edit the heading directly.
Are `(c)`/`(tm)` in the license footer safe?
Yes. Those marks are outside the matched emoji ranges and are preserved exactly.
How do I review the change before committing?
Run Replace mode first. Every former emoji shows as a bracketed token, giving you a readable diff. Then run Strip for the final file.
What about country-flag emoji in a translations section?
Each flag is two regional-indicator code points, so in Replace mode it becomes two bracket tokens and in Strip mode both are removed. Use plain language names if you want readable labels.
Is anything uploaded?
No. The transform runs in your browser, which suits private internal forks and pre-release READMEs. Nothing about the file leaves your machine.
Can it clean multiple repo files at once?
No — one file per run. For a docs folder, combine with md-merger, clean, then re-split with md-splitter.
Could a non-emoji `:word:` get removed?
Yes. The shortcode matcher catches any lowercase :word:, so a status token like :passing: could be affected. Review with Replace first and restore any literal tokens.
Does Replace name a Unicode emoji like [rocket]?
Only for shortcodes. :rocket: becomes [rocket], while a literal Unicode rocket is wrapped as [ glyph ]. The bracketed Unicode token is a marker, not a name.
Will it touch Markdown headings, lists, or tables?
Only to remove emoji within them. Heading markers, list bullets, table pipes, and link syntax are not emoji and are preserved — just the emoji characters inside the text are removed or bracketed.
Privacy first
All Markdown processing runs locally in your browser using JavaScript. No file is ever uploaded to JAD Apps servers — only metadata counters are saved for signed-in dashboard stats.