Generate and remove Zalgo text in the Browser
Specify above/middle/below the character, intensity, conversion rate, target characters, and a reproduction seed, then review the results and statistics. When removing, choose the target range from two modes.
Open Zalgo text generation/destruction toolConclusion: Remove only known marks first, and try removing all marks on a comparison copy
"Only characters used by this tool" removes only marks that match the built-in pool. "All combining characters" targets Unicode marks generally, making it more resilient to external Zalgo text but potentially damaging normal language notation.
The original purpose of a mark cannot be inferred from the removal process. If an original accent and added Zalgo use the same code point, they cannot be perfectly distinguished without the original.
Before overwriting the original text with the unmarking result, compare Original, conservative unmarking, and removing all Marks.
Factors for choosing a removal method
Check whether the source can be identified, whether it contains ordinary accents, and whether Japanese appears as an NFD-equivalent sequence.
If you know it was generated by this tool, remove only known marks; only if the source is unknown and unreadable, try removing all marks in a copy.
| Item | How to check | judgment |
|---|---|---|
| Generation source | Check whether it is this tool | Remove known Marks |
| language | Check accents and voiced sound marks | Be careful when clearing all Marks |
| Remaining Marks | Code point analysis | Force unlock if necessary |
| Restore | Compare with Original | Do not save if it does not match |
Procedure for removing Zalgo gradually
- Duplicate the input to preserve the Original.
- Limit unmarking to “characters used by this tool only.”
- Remove Zalgo and check remaining Marks and readability.
- Only when necessary, try “remove all combining marks” in a separate copy.
- Compare accents, decomposed voiced and semi-voiced sound marks, meaning, and character count to decide which result to use.
Because external generators use different mark pools, some marks remaining after safety-oriented removal is not a failure.
Conditions where complete restoration is not possible
- The Original was not saved.
- Combining Marks existed before Zalgo was added
- Already normalized or replaced at the paste destination
- The base character itself was deleted or changed.
- Marks from multiple generators are mixed.
Zalgo is a sequence of Unicode combining characters, not a Font
| Display example | Internal representation | meaning |
|---|---|---|
| A | U+0041 | Base characters only |
| Á | U+0041 + U+0301 | Add one Combining Acute Accent to the base. |
| Zalgo-style A | U+0041 + multiple Marks | A string with marks above, through, and below the base |
| Change CSS font | Keep U+0041 | Change only the glyph without changing the code point |
Unicode General_Category M includes Nonspacing Mark, Spacing Combining Mark, and Enclosing Mark. Many characters used by the Zalgo Generator are combining marks, but combining characters are also needed for normal language notation, such as accents, phonetic marks, and Japanese voiced and semi-voiced sound marks. Do not conclude that "Marks are unnecessary" or that "U+0300–U+036F contains all Combining Marks."
Choose between safety-oriented and stronger removal methods
| Removal method | Deletion target | Suitable scenarios | Main risks |
|---|---|---|---|
| Only characters used in this tool | Characters included in the built-in Zalgo Mark Pool | Output generated by this tool, when you want to retain normal accents | Marks unique to external generators may remain |
| all combining characters | Equivalent to Unicode Property Escape \p{M} | When you want to remove unknown-source Zalgo aggressively | Accents, decomposed voiced and semi-voiced sound marks, and symbols from other languages may also be lost |
| Return to the original data | Original retained before editing | When complete restoration is required | Cannot be used without the Original. |
"All combining characters" is not a universal safe removal option. Preserve the original for important text, compare before and after removal, and then save or send it.
Count one visible character and internal length separately
| unit | Whether it increases with Zalgo | Verification purpose |
|---|---|---|
| Grapheme Cluster | Do not increase when the base and mark appear as one grapheme. | The number of characters recognized by the user and cursor movement |
| Code Point | Increases for each added mark | Unicode analysis, generation limits, string scanning |
| UTF-16 Code Unit | Marks in the BMP normally increase by 1 each, while supplementary-plane characters count as 2. | JavaScript String.length, Legacy API |
| UTF-8 Byte | Increases by the encoding length of the mark | Database columns, API payloads, file size |
JavaScript String.length is the number of UTF-16 code units, not the number of visible characters. The current tool splits input by grapheme when Intl.Segmenter is available, and counts code points in output with Array.from. Check destination limits by code point count and byte count as well as grapheme count.
Normalization alone does not complete Zalgo removal
| Format | Main processing | Zalgo caution |
|---|---|---|
| NFC | Compose sequences where possible after canonical decomposition | Reorder and combine, but do not remove a large number of marks. |
| NFD | Canonical Decomposition | Precomposed accents and voiced marks may split into base characters and marks, increasing the number of marks |
| NFKC | Compose after compatibility decomposition | Changes compatibility representations, but is not solely for removing Zalgo and can also alter meaningful notation differences |
| NFKD | Compatibility Decomposition | Compatibility decomposition and canonical decomposition can increase irreversible differences |
Normalization is a specification for making equivalent Unicode representations easier to handle; it is not a feature that automatically identifies unnecessary decoration. A design may use NFC before and after a removal process, but apply it only after deciding the purpose, storage format, and round-trip requirements. The current Zalgo tool does not perform normalization.
Features and boundaries that can be checked with DevelopTools
| Item | Current tool operation |
|---|---|
| Generation position | Select the top, middle, or bottom of a character individually and add combining characters from the selected Mark Pool. |
| strength | You can specify weak, standard, strong, or maximum strength, plus custom strengths from 1 to 20 |
| Target | Text is included. Toggle digits, whitespace, symbols/emoji, and selected ranges in settings. Line breaks are always preserved. |
| Reproducibility | The same input, settings, and seed can reproduce the same generated result. |
| Remove | Choose between two modes: "only characters used by this tool" and "all Unicode combining characters." |
| Statistics | Display the input grapheme count, output code point count, converted character count, added/removed mark count, and UTF-8 size. |
| Upper limit | Limit input to 50,000 graphemes, output to 500,000 code points, and each grapheme to 40 marks. |
| Unsupported | Does not perform NFC/NFD/NFKC/NFKD normalization, list Unicode names, individually edit mark positions, or fully restore original strings |
| Privacy | Do not send input or results to the server; save only settings in the browser's LocalStorage. |
The current UI names the removal modes "All combining characters" and "Only characters used by this tool." This article describes the latter as safety-oriented and the former as stronger but potentially destructive removal. Do not refer to nonexistent buttons named Safe Remove or Aggressive Remove.
Primary sources used to check specifications
- Unicode UAX #15:Unicode Normalization Forms
- Unicode UAX #29:Unicode Text Segmentation
- Unicode UAX #44:Unicode Character Database
- MDN:Unicode character class escape
- MDN:Intl.Segmenter
- MDN:String.length
Use UAX #15 for normalization, UAX #29 for grapheme clusters, and UAX #44 for General_Category and Combining Class. Compare JavaScript Unicode property escapes, Intl.Segmenter, and String.length with MDN specification explanations, and do not treat only a specific block as all marks.
Example: Remove decoration from a string containing Japanese and accents
After removing known marks, check whether "が" and "é" are retained.
Because removing all marks can change "か" or "e", prioritize safer results.
- Keep the Original.
- Remove known Marks
- Compare Japanese and Latin text
- Analyze remaining marks
- Remove all marks only when necessary.
Even if appearance improves, check that language information has not been lost.
Frequently asked questions
- Is Zalgo text a special font?
- No. It is a string created by adding multiple Unicode combining characters to a normal Base Character. The overlap varies by Font, but the copied data is a sequence of Code Points.
- Can I safely restore the original by deleting all combining characters?
- Cannot guarantee. Ordinary accents, pronunciation marks, and decomposed voiced/semi-voiced marks are also Marks. First remove only the Marks known to this tool and check whether required language information remains.
- Are input and generated results sent to the Server?
- The current Zalgo text generation/removal Tool processes in the Browser and does not send input or results to the Server. Only display and generation settings are stored in LocalStorage.