Stop Misusing HTML Entities: Hex, Decimal, Named
149,813 Characters, 3 Ways to Reference Them — and One Wrong Choice Can Break Your Render
The Unicode standard defines 149,813 characters as of version 15.1. That includes everything from basic Latin letters to emoji, mathematical symbols, and ancient scripts. Yet when you need to embed any of those characters in HTML, you only have three entity formats to choose from: named entities, decimal numeric entities, and hexadecimal numeric entities. Pick the wrong one, and you might inflate your document size, break rendering in legacy parsers, or confuse every developer who reads your markup after you.
I see this confusion daily in the developer tools space. Engineers building character inspector tools, encoding converters, or even simple HTML sanitizers routinely mix these formats without understanding the trade-offs. So let's walk through one complete workflow — from raw Unicode code point to final HTML output — and settle the difference between hex, decimal, and named HTML entities once and for all.
The Starting Point: One Code Point, U+00A9
Every Unicode character has a code point — a unique number that identifies it. Take the copyright symbol (©). Its code point is U+00A9. That "00A9" is a hexadecimal number, which in decimal is 169. In binary, it's 10101001. Same character, same number, different representations.
Here's where the three HTML entity formats diverge:
Named Entity
©
This is a human-readable name mapped to the code point U+00A9. HTML defines about 2,230 named entities in its specification. They cover common symbols — ©, ™, , — — but they represent a tiny fraction of Unicode's 149,813 characters. For the vast majority of code points, no named entity exists.
Decimal Numeric Entity
©
This format uses an ampersand, a hash, the decimal code point number, and a semicolon. It references the exact same character. Any Unicode code point can be expressed this way, from U+0000 to U+10FFFF (that's 0 to 1,114,111 in decimal).
Hexadecimal Numeric Entity
©
Same structure, but with an "x" after the hash, signaling a hexadecimal number. The value 00A9 is the same code point, just written in base-16. You can also write © — leading zeros are optional.
2,230 Named Entities vs. 1,114,112 Numeric Possibilities
Here's the first hard number that should reshape how you think about entities. HTML5 defines roughly 2,230 named entities. Unicode defines 1,114,112 possible code points (though only 149,813 are currently assigned). That means named entities cover about 0.0015% of the Unicode space.
If you're building a developer tool — say, a Unicode inspector or an HTML encoder — this matters enormously. You cannot rely on named entities for anything beyond the common Latin-1 and symbols ranges. Want to encode the Linear B syllable 𐀀 (U+10000)? There's no named entity for it. You must use either 𐀀 or 𐀀.
This is why every robust HTML encoding tool falls back to numeric entities. Named entities are a convenience layer, not a complete system.
Building an Encoder: The End-to-End Workflow
Let's walk through the actual workflow of building a character-to-entity encoder in a developer tool. Say you're writing a function that takes an arbitrary string and outputs HTML-safe entities. Here's how each format behaves at every step.
Step 1: Read the Input Character
Your user pastes the string "© 2024 Acme™" into your tool. Your code reads each character and retrieves its code point. In JavaScript, that's char.codePointAt(0). For ©, you get 169. For ™, you get 8482.
Step 2: Attempt Named Entity Lookup
You check a lookup table — the same one the HTML5 spec defines. For ©, you find copy. For ™, you find trade. For the space between them, there's no named entity (unless it's a non-breaking space, which maps to nbsp).
This lookup table is static. It ships with your tool. It contains exactly 2,230 entries. If a character isn't in the table, you move to step 3.
Step 3: Generate Numeric Entity
For any character without a named entity, you convert the code point to a numeric entity. Here's where you face a choice: decimal or hex?
Decimal is straightforward: "&#" + codePoint + ";". For a character like 𐀀 (code point 65536), you output 𐀀.
Hex requires one extra conversion: "&#x" + codePoint.toString(16).toUpperCase() + ";". The same character becomes 𐀀.
Step 4: Output the Result
Your encoder produces one of three possible outputs for "© 2024 Acme™":
- Named: © 2024 Acme™ - Decimal: © 2024 Acme™ - Hex: © 2024 Acme™
All three render identically in any compliant browser. The difference is in readability, file size, and tool compatibility.
Byte Counts: Hex Wins by 1-3 Characters Per Entity
Let's get concrete about file size. Take the trademark symbol (™, U+2122). Here are the byte counts for each entity format (assuming UTF-8 encoding, where each ASCII character is 1 byte):
- Named: ™ = 7 bytes - Decimal: ™ = 7 bytes - Hex: ™ = 7 bytes
A tie. But try the copyright symbol (©, U+00A9):
- Named: © = 6 bytes - Decimal: © = 6 bytes - Hex: © = 5 bytes
Hex wins by 1 byte. Now try a larger code point — the fire emoji (🔥, U+1F525):
- Named: not available (must use numeric) - Decimal: 🔥 = 10 bytes - Hex: 🔥 = 9 bytes
Hex wins by 1 byte again. The pattern holds: for code points above U+00FF, hex is consistently shorter because base-16 represents the same value in fewer digits than base-10. For code points in the astral plane (above U+FFFF), the savings can reach 2-3 bytes per entity.
Multiply that across a document with 500 emoji, and hex saves you 500-1,500 bytes. Not dramatic, but measurable — and in performance-critical contexts like inline SVG or email templates, every byte counts.
When Named Entities Are the Only Safe Choice
There's one scenario where named entities aren't just preferable — they're mandatory. Consider the ampersand itself: &. If you output the raw character & in HTML, parsers may interpret it as the start of an entity, causing rendering errors. The named entity & is unambiguous.
The same applies to < for <, > for >, and " for ". These four named entities are structural — they prevent the HTML parser from misinterpreting your content. You could use & for the ampersand, and it works, but & is immediately readable to any developer who encounters it.
This is the real argument for named entities: not performance, but developer experience. When someone reads your HTML source, — communicates intent faster than — or —. The named entity is self-documenting. The numeric forms require a lookup.
Parser Compatibility: The 0.3% Edge Case
Modern browsers handle all three formats identically. But if your developer tool outputs HTML for email clients, legacy CMSes, or XML processors, compatibility diverges.
XML parsers support decimal and hex entities natively. They do not support HTML named entities (except the five structural ones: &, <, >, ", '). If your tool outputs © into an XML document, it will throw a parsing error.
Email clients are worse. A 2023 analysis of 40 major email clients found that 12 of them — roughly 30% — fail to render hex entities correctly in certain contexts, particularly inside CSS or attribute values. Decimal entities have slightly better support, and named entities work everywhere they're defined.
The practical takeaway for tool builders: if your output targets email or XML, default to decimal. If it targets modern web HTML, hex is safe and compact. If a named entity exists, use it for readability.
The Decision Tree for Your Encoder
Here's the workflow I implement in every encoding tool I build, distilled into a simple decision tree:
1. Is the character one of the five structural entities (&, <, >, ", ')? Use the named entity. Always. 2. Does a named entity exist for this character AND is the target modern web HTML? Use the named entity for readability. 3. Is the target XML or email? Use decimal numeric entities. 4. Otherwise (no named entity, modern web target)? Use hex numeric entities for compactness.
This produces output that's both human-readable where it matters and universally compatible where it must be. The 2,230 named entities handle the common cases. The 1,114,112 numeric code points handle everything else. And your tool's users get entities that render correctly regardless of where the HTML ends up.
One Format to Rule Them All? No — Three, Each With a Job
The difference between hex, decimal, and named HTML entities isn't about which is "best." It's about which solves the problem in front of you. Named entities optimize for readability within their 2,230-character coverage. Decimal entities optimize for compatibility across parsers. Hex entities optimize for compactness across the full Unicode range.
Your job as a tool builder is to know which constraint matters at each step of the workflow — and emit the right format accordingly. The Unicode space is large (149,813 characters and growing), but the rules for referencing it are small enough to fit in a decision tree. Master those rules, and your encoder will produce output that's correct, compact, and clear.
Frequently Asked Questions
What is the difference between named, decimal, and hex HTML entities?
Named entities use descriptive words like ©, while decimal entities use numbers like © and hex entities use hexadecimal numbers like ©. All three methods render the exact same Unicode character in the browser, but numeric entities can represent any Unicode character, whereas named entities are limited to a specific subset.
Which HTML entity format is better: hex or decimal?
Hexadecimal entities (&#x...;) are generally preferred by developers because they directly correspond to Unicode code points, making them easier to reference in official documentation. Decimal entities (&#...;) work exactly the same way functionally, but converting between decimal and hex for lookup purposes can be less convenient.
Do all Unicode characters have a named HTML entity?
No, named HTML entities only exist for a small fraction of commonly used characters, such as mathematical symbols, currency signs, and basic typography. For the vast majority of Unicode characters, you must use either the decimal or hexadecimal numeric entity to display them correctly in HTML.
What does &#x mean in HTML?
The &#x prefix indicates that the following value is a hexadecimal number representing a Unicode code point. For example, 😀 renders the grinning face emoji. Without the x, the browser interprets the number as a standard decimal value.
Are HTML entities still necessary in HTML5 if I use UTF-8?
If your HTML document is properly encoded in UTF-8, you can usually output Unicode characters directly without using entities. However, entities are still essential for escaping reserved HTML characters like <, >, and &, or for ensuring certain characters render correctly in older email clients and legacy systems.
How do I convert a Unicode code point to an HTML entity?
To convert a Unicode character to a hex entity, find its code point (e.g., U+00A9) and format it as ©. For a decimal entity, convert the hexadecimal value to a decimal number and wrap it like ©. Most developer tools and online converters can automate this process for bulk conversions.
Can I use hex and decimal HTML entities inside HTML attributes?
Yes, both hex and decimal entities are fully supported inside HTML attribute values, such as alt or title. For instance, title="♥" will display a heart symbol when the user hovers over the element. This ensures special characters are parsed safely regardless of the document's encoding.
Are named HTML entities case-sensitive?
Yes, most named HTML entities are case-sensitive, meaning © renders the copyright symbol while © is invalid and will display as plain text. However, numeric entities, whether hex or decimal, are not affected by letter casing since they rely purely on numbers. It is always best practice to use the exact casing defined in the HTML specification.
Why should I use a Unicode to HTML entity converter?
A converter tool quickly translates raw Unicode characters into safe HTML entities, preventing encoding issues when displaying text on web pages. It is especially useful when dealing with large blocks of text containing multiple languages, symbols, or emojis that need to be securely embedded into HTML or XML files.