HTML Encoder / Decoder
Encode text to HTML entities for safe display, or decode named, numeric, and hex entities back to plain text. Runs entirely in your browser.
Calculator
Output
Text ↔ HTML Entities
—
Output Size
— B
Input Size
— B
Size Change
—
Decoding Failed
—
Common causes:
- A misspelled named entity (e.g.
&without a semicolon, or an entity name that doesn't exist) - A numeric entity with non-digit characters, e.g.
&#zzz;or&#xzzz; - A numeric entity referencing a codepoint outside the valid Unicode range
Operation
—
How HTML Encoder / Decoder Works
What is HTML Encoding?
HTML encoding (also called HTML escaping) replaces characters that have special meaning in HTML
markup — < > " ' & — with their entity equivalents, so they
display as literal text instead of being interpreted as markup. Encoding <b> as
<b> means a browser shows the literal characters
“<b>” on the page, rather than rendering it as a (would-be) bold tag.
Why HTML Encoding Matters
Any time user-supplied or external text is inserted into an HTML page, it must be encoded first —
otherwise a value containing <script>...</script> doesn’t just display
oddly, it executes. This is the foundation of Cross-Site Scripting (XSS) prevention:
encoding untrusted text before it becomes part of an HTML document turns a potential attack payload
into inert, harmless display text. Beyond security, encoding is also simply necessary for correctness
— showing a literal < or & character in rendered HTML requires
encoding it, or the browser will try to parse it as markup.
Common HTML Entities
| Character | Named Entity | Meaning |
|---|---|---|
& | & | Ampersand |
< | < | Less-than (opens a tag) |
> | > | Greater-than (closes a tag) |
" | " | Double quote (attribute delimiter) |
' | ' | Single quote / apostrophe |
| | Non-breaking space |
© | © | Copyright sign |
This tool encodes the first five — the characters that are actually unsafe to leave unescaped in HTML output — matching the standard set encoded by every major web framework’s default template auto-escaping (Django, Jinja2, React’s JSX, and this project’s own templates all encode this same set by default).
XSS Prevention
Cross-Site Scripting happens when unescaped user input is inserted directly into a page’s
HTML, letting an attacker’s <script> tag or event handler attribute
(onerror=, onclick=) run in another user’s browser. Encoding
< and > alone neutralizes tag injection; encoding " and
' additionally prevents an attacker from breaking out of an HTML attribute’s quotes.
This is why all five characters matter together, not just the two most obviously
“tag-like” ones. Encoding is one layer of defense, not the whole strategy
— see Security Notes below.
Named vs Numeric Entities
| Named | Numeric (decimal) | Numeric (hex) | |
|---|---|---|---|
| Example | & | & | & |
| Readability | High — self-descriptive | Low | Low |
| Coverage | ~2,200 defined names (HTML5) | Any Unicode codepoint | Any Unicode codepoint |
| Use case | Common characters, hand-written HTML | Generated output, arbitrary characters | Generated output, matches Unicode notation (U+0026) |
Named entities exist only for a defined, finite set of characters and are easiest for humans to
read. Numeric entities (decimal &#NNN; or hexadecimal &#xHHH;) can
represent any Unicode codepoint, including characters with no named entity at all —
which is why this tool decodes all three forms.
Unicode Entities
A numeric entity’s number is the character’s Unicode codepoint. 😀
and its hex equivalent 😀 both decode to 😀 (U+1F600, GRINNING FACE) —
the same mechanism used for emoji, accented letters, and any script beyond the entities with dedicated
names. This tool validates that a numeric entity’s codepoint is actually a legal Unicode scalar
value (not a UTF-16 surrogate half, not beyond U+10FFFF) before decoding it.
Common Mistakes
- Encoding twice. Running already-encoded text through the encoder again turns
&into&amp;— each&gets encoded again, compounding. Encode raw text exactly once, at the point it’s inserted into HTML. - Relying on encoding for a context it doesn’t protect. HTML entity encoding
protects HTML element and attribute content. It does not make text safe inside a
<script>block, a URL, or a CSS value — those each need their own escaping rules (see the URL Encoder for URLs). - Forgetting apostrophes. Some hand-rolled escaping only handles
< > &and skips quotes, which is enough to prevent tag injection but not attribute-breakout attacks — this tool always encodes all five. - Assuming decode always succeeds. Not every
&...;-shaped string is a valid entity — this tool reports a malformed entity as a clear, specific result rather than silently leaving it unconverted.
Security Notes
HTML encoding is not encryption and provides no confidentiality — it is
fully and instantly reversible, and its only purpose is controlling how a browser interprets
characters. It is also context-specific: text that’s safe inside an HTML
element’s text content is not automatically safe inside an HTML attribute, inside a
<script> tag, or inside a URL — each context has its own escaping rules, and
using the wrong one is a common source of real vulnerabilities. When building software, prefer your
framework’s built-in auto-escaping (as this project’s own Django templates use) over
manual encoding wherever possible — manual encoding is easy to forget in one spot out of many.
Worked Examples
| Input | Encoded |
|---|---|
<script>alert(1)</script> | <script>alert(1)</script> |
Tom & Jerry | Tom & Jerry |
She said "hi" | She said "hi" |
Related Tools
Escaping HTML is one of several encoding tasks a JSON payload or URL might need: inspect or reformat JSON with the JSON Formatter, percent-encode a value for a URL with the URL Encoder, convert binary data with the Base64 Encoder, inspect a JWT, or validate a pattern that extracts HTML-unsafe characters with the Regex Tester.
Accuracy & Sources
Last reviewed: July 2026. Formula source: WHATWG HTML Living Standard — Named character references. All calculations run in your browser. No data is sent to any server.
Frequently Asked Questions
HTML encoding converts characters with special meaning in HTML markup — < > " ' & — into entity forms like < and &, so they display as literal text instead of being interpreted as tags or attribute syntax. It's essential whenever user-supplied or external text is inserted into an HTML page, both for correct display and to prevent Cross-Site Scripting (XSS) attacks.
It's the core mechanism, but not the whole story. Encoding < > " ' & neutralizes tag injection and attribute-breakout attacks when text is placed inside HTML element content or a quoted attribute. It does NOT make text safe inside a <script> block, a URL, or a CSS value — each of those contexts needs its own specific escaping. Using the wrong escaping for the context is a very common source of real XSS vulnerabilities.
A named entity like & or < is a human-readable label for a specific character, drawn from a fixed list of about 2,200 HTML5-defined names. A numeric entity — decimal (&) or hexadecimal (&) — specifies a character by its raw Unicode codepoint instead, and can represent any character, including ones with no assigned name. This tool decodes all three forms.
Yes, via numeric entities. 😀 (decimal) and 😀 (hex) both decode to the same grinning-face emoji, because a numeric entity's number IS the character's Unicode codepoint. Named entities only exist for a limited, predefined set of characters, so emoji and most non-Latin scripts require the numeric form.
The three causes: a named entity that isn't a real HTML5 entity name (a typo, or an invented name), a numeric entity whose digits aren't actually digits (like &#zzz; or &#xzzz;), or a numeric entity whose codepoint is outside the valid Unicode range. This tool reports exactly which malformed entity was found and why, at its exact position in your text.
Each & in the already-encoded text gets encoded again — & becomes &amp;, which decodes back to & (not the original character) if decoded only once. This is called double encoding, and it compounds with each additional encode pass. Encode raw, unescaped text exactly once, at the point where it's about to be inserted into HTML.
No — encoding and decoding run entirely in your browser via JavaScript, and your text never leaves your device while you type. Only if JavaScript is disabled does the form fall back to a transient server-side computation, which is not stored or logged either way.