← Guides

Zero-width characters: the invisible marks that really are in your text

ZWSP, ZWNJ, ZWJ, word joiners and the BOM. What they are, why they survive copy-paste, and how to find every one.

Hidden characters · 2 min read

Some Unicode characters occupy no horizontal space and render as nothing at all. They are fully present in the data, they survive copy-paste into almost any editor, and you will never see them.

The characters

CodepointNamePurpose
U+200BZero Width SpaceA line-break opportunity with no visible gap
U+200CZero Width Non-JoinerPrevents ligature formation in some scripts
U+200DZero Width JoinerForces joining; also builds emoji sequences
U+2060Word JoinerPrevents a line break, no width
U+FEFFZero Width No-Break Space / BOMByte-order mark, often a file artefact
U+00ADSoft HyphenRenders only if a line breaks there

Every one has a legitimate typographic purpose. That is exactly what makes them useful for hiding things: their presence is not inherently suspicious.

Why they are a marker

Two reasons.

They change the bytes without changing the appearance. Two documents can look pixel-identical and differ in their underlying data. That is enough to distinguish one copy from another — the basis of any per-recipient tracking scheme.

They can encode a payload. Treat one character as 0 and another as 1 and you can write arbitrary binary into the gaps between words. A few hundred zero-width characters spread through an article is plenty for an identifier.

Where they come from in practice

Most of the time, nothing sinister:

  • PDF and word-processor exports insert them around line breaks and hyphenation.
  • CMS and rich-text editors add them when handling pasted content.
  • Emoji legitimately contain U+200D — the joiner is how multi-person and skin-tone sequences are built. This is worth knowing, because naive cleanup that strips all ZWJ will break emoji.
  • Copy-paste from web pages carries whatever the page had.

So finding them does not mean someone tracked you. It usually means your text passed through software.

How to find them

You cannot, by eye. You need a tool that iterates codepoints and reports by category. That is exactly what a character-level scan does, and because it is pure matching rather than a guess, the count it gives is exact — no confidence score, no probability.

Run a free scan and the report will list each type it found, with counts, and draw a chip at every position where one sits so you can see where they are.

How to remove them

Deleting the codepoints is lossless for the invisible ones — U+200B, U+2060, U+FEFF, U+00AD carry no meaning in ordinary prose. Removing them cannot change what your text says.

The care point is U+200D inside emoji sequences, where deletion does change meaning. Any cleanup worth using handles that distinction rather than blanket-stripping.

After cleaning, re-scan. A count of zero is a verifiable result, which is the whole advantage of working at the character level.

Related: Unicode tag characters · variation selectors and steganography

Check your own text for every marker described here. Free, instant, and it never leaves your browser.

Run a free scan

Related