An HTML entity encoder converts the five reserved HTML syntax characters into safe character references so that a string can be placed inside an HTML document without being parsed as live markup, and the matching decoder reverses the process by resolving those references back into literal Unicode characters using the browser's own HTML parser. The HTML Entity Encoder / Decoder performs both directions entirely in the browser — nothing is uploaded, and no document sanitization is performed. In basic encode mode, the ampersand becomes the named reference &, less-than becomes <, greater-than becomes >, double quote becomes ", and apostrophe becomes the decimal numeric reference '. Ampersand is encoded first so that any reference the encoder creates in the same pass is not itself re-encoded. An optional non-ASCII mode performs the same syntax protection and additionally rewrites every Unicode code point above ASCII 126 as an uppercase hexadecimal numeric reference, iterating by code point rather than UTF-16 code unit so that a supplementary character such as 😀 becomes the single reference 😀 instead of two invalid surrogate halves. Decode mode uses a detached textarea element so the active WHATWG HTML parser applies the full current named-character-reference table — including legacy aliases and references that resolve to more than one code point — and the result is returned as plain text in a read-only area.

What HTML Entities Actually Represent
HTML uses three syntax roles that share the same byte stream: ordinary text, tags such as <p>, and entities such as &. The parser must be able to tell where each role begins and ends, so the HTML specification reserves five characters. The ampersand introduces a reference, less-than and greater-than delimit tags, and double quote or apostrophe delimit attribute values. If you write those characters in a text node or attribute value as literal bytes, the parser will treat them as markup instead of text. An HTML entity is a short replacement sequence that begins with & and ends with ; that the parser resolves to the original character. There are three flavours: named references such as © for ©, decimal numeric references such as © for the same character, and hexadecimal numeric references such as ©. The complete list of named references is defined by the WHATWG HTML Living Standard, which documents legacy aliases and references that expand to more than one code point.
Modern UTF-8 HTML documents can contain the © character directly as bytes — the WHATWG and MDN both note that unnecessary references should be avoided. So why encode at all? Three situations still come up. First, you may need to embed arbitrary text inside an HTML element or attribute and cannot trust the source to be safe; escaping the five reserved characters is the minimum requirement. Second, you may be sending text through a transport that mangles anything above ASCII, such as a legacy mail template, an older CMS field, or a teaching example, in which case the non-ASCII mode writes those code points as numeric references so they survive intact. Third, you may receive a string that already contains references and want to see the resolved text — for example when reading exported HTML, debugging an API response, or studying how a particular reference behaves.
Choosing the Right Mode: Basic vs Non-ASCII
The encode direction has two modes that differ in how they treat characters above ASCII 126. The table below summarises the differences; both modes share the same handling of the five reserved characters.
| Aspect | Basic mode | Non-ASCII mode |
|---|---|---|
| Reserved characters &, <, >, ", ' | Replaced with &, <, >, ", ' | Same replacements as basic mode |
| ASCII letters, digits, spaces, tabs, line breaks | Left as-is | Left as-is |
| Code points above ASCII 126 (e.g. ©, é, 😀) | Left as raw UTF-8 bytes | Rewritten as uppercase hex numeric references such as ©, é, 😀 |
| Iteration granularity | Not applicable | Unicode code points, so an emoji becomes one valid reference |
| Typical use | Readable source for a text node or attribute value | Legacy transport, teaching example, comparison task, or numeric-reference workflow |
| Source readability after conversion | High — most characters remain literal | Lower — every non-ASCII glyph becomes a numeric reference |
Default to basic mode whenever the goal is to keep the source readable and the receiving context is plain UTF-8 HTML. Reach for non-ASCII mode only when a numeric-reference representation is genuinely required by a legacy workflow, a transport that strips high bytes, a teaching example, or a side-by-side comparison.
Encoding or Decoding a String
- Open the HTML Entity Encoder / Decoder in your browser and choose the direction — Encode characters if you want to escape the five reserved characters (and optionally non-ASCII code points), or Decode references if you want to resolve named, decimal, or hexadecimal references back into Unicode text.
- If you chose Encode, pick a mode. Use Basic for readable UTF-8 output that still protects HTML syntax; use Non-ASCII only when every code point above 126 must appear as an uppercase hex numeric reference.
- Paste the source text into the input area. Keep the input under 500,000 JavaScript characters so the browser stays responsive and the parser returns promptly.
- Select the conversion button that matches your chosen direction and mode. The browser performs the conversion locally — no network request is made and no remote table is fetched.
- Inspect the result before copying. In encode output, confirm that every & originated from your input rather than from a newly created reference that should have stayed literal, and that angle brackets you intended as text now read < and >. In decode output, scan for characters that look like markup, particularly angle brackets, slashes, and the word script.
- Copy the result only into an appropriate context — an HTML text node, an attribute value that is then placed by a trusted templating engine, a legacy transport, or a teaching document. Never paste decoded text directly into an unsafe innerHTML sink.
Reading the Output Without Surprises
After a conversion, the result is returned as plain text in a read-only area. For an encode pass, scan from top to bottom for three things. First, every & in the output should be the start of a reference whose name or number came from your input, not from the encoder's own work; the encoder mitigates this by writing the ampersand reference first, but the human eye still has the final say. Second, the angle brackets that you intended as literal text should now read < and >, which makes them visually obvious. Third, any code point above ASCII 126 that you asked to be rewritten should appear as an uppercase hexadecimal numeric reference prefixed by &#x and ending with ;, while every character below 127 should appear as itself. For a decode pass, scan the output for characters that might look like markup when you paste them — angle brackets, slashes, quotes, and the word script are common giveaways — and remember that the tool did not execute anything; the strings <script> and </script> are simply text at this point.
The encoder does not rewrite ordinary printable characters such as letters, digits, spaces, tabs, or line breaks. Modern UTF-8 HTML can carry Unicode directly, and a numeric reference for, say, the letter e would only add noise. The tool follows the WHATWG and MDN guidance of avoiding unnecessary references, so basic mode keeps readable source readable.
Decoded Output Is Not Trusted Markup
A reference such as <script> decodes to the ten-character string <script>. The tool returns that as plain text into the read-only area; the page does not insert the string into the live DOM, run it as JavaScript, or render it as a tag. The danger appears only if you then copy the decoded string into an unsafe sink such as element.innerHTML, document.write, a jQuery .html() call, or any other context that parses its argument as HTML. In that situation, the literal characters <script> become a live <script> tag in the recipient page. Treat every decoded string as untrusted data. Use context-aware escaping at the final output boundary — a trusted templating engine, framework auto-escaping, or a vetted sanitizer — rather than assuming that having escaped or decoded a value once is sufficient for every downstream use.
The same caution applies to attribute values, javascript: URLs, and event-handler attributes. The encoder does not strip them, the decoder does not neutralise them, and the browser will parse them as soon as the surrounding template asks it to.
Where HTML Escaping Stops Working
HTML entity escaping protects only the five reserved syntax characters inside an HTML text node or attribute value. It is not the same as escaping for a URL parameter (which uses percent-encoding), a JavaScript string literal (which requires JSON-style or similar escaping), a CSS value, a SQL query, or an HTTP header. Each of those contexts has its own metacharacters and its own escaping rules, and using HTML escaping in the wrong place either fails to protect the data or produces a malformed string. The HTML Entity Encoder / Decoder is also not a sanitizer — it does not strip <script> tags, neutralise javascript: URLs, or apply a Content Security Policy. If you need to place user-supplied HTML into a page, use a vetted sanitizer with an allow-list, and if you only need to display the text, render it as text in the first place so the browser never parses it as markup.
If the downstream system uses XML rather than HTML, remember that XML defines a much smaller set of built-in entities (&, <, >, ", ') and follows different parsing rules; the WHATWG named-reference table is HTML-specific. For large or unfamiliar blocks, paste a small representative sample first, run the conversion, and inspect ampersands and angle brackets before processing the whole input. The page does not save history, fetch a remote table, or transmit the input — every step of the conversion happens inside the current tab.