entities vs he vs html-entities
HTML Entity Encoding and Decoding in JavaScript
entitieshehtml-entitiesSimilar Packages:

HTML Entity Encoding and Decoding in JavaScript

entities, he, and html-entities are npm packages designed to encode and decode HTML entities in JavaScript applications. They help safely handle user input, prevent XSS vulnerabilities, and ensure proper rendering of special characters like <, >, &, and non-ASCII symbols by converting them to or from their corresponding HTML entity representations (e.g., &lt;, &gt;, &amp;). Each package offers slightly different APIs, performance characteristics, and feature sets for working with HTML entities in both browser and Node.js environments.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
entities0375392 kB8a month agoBSD-2-Clause
he03,666-237 years agoMIT
html-entities0687132 kB6a year agoMIT

HTML Entity Handling in JavaScript: entities vs he vs html-entities

When you’re building web apps, you often need to convert special characters into safe HTML entities (like turning <script> into &lt;script&gt;) or decode them back for display. The three main libraries for this in the JavaScript ecosystem are entities, he, and html-entities. They all solve the same core problem but with different design philosophies, APIs, and trade-offs. Let’s compare them head-to-head.

🔤 Basic Encoding and Decoding

All three packages support encoding (converting characters to entities) and decoding (converting entities back to characters), but their function signatures differ.

entities uses simple top-level functions:

import { encode, decode } from 'entities';

const encoded = encode('<div>Hello & "world"</div>');
// '&lt;div&gt;Hello &amp; &quot;world&quot;&lt;/div&gt;'

const decoded = decode('&lt;div&gt;Hello &amp; &quot;world&quot;&lt;/div&gt;');
// '<div>Hello & "world"</div>'

he also provides straightforward functions:

import * as he from 'he';

const encoded = he.encode('<div>Hello & "world"</div>');
// '&lt;div&gt;Hello &amp; &quot;world&quot;&lt;/div&gt;'

const decoded = he.decode('&lt;div&gt;Hello &amp; &quot;world&quot;&lt;/div&gt;');
// '<div>Hello & "world"</div>'

html-entities requires creating an instance first:

import { Html5Entities } from 'html-entities';

const entities = new Html5Entities();

const encoded = entities.encode('<div>Hello & "world"</div>');
// '&lt;div&gt;Hello &amp; &quot;world&quot;&lt;/div&gt;'

const decoded = entities.decode('&lt;div&gt;Hello &amp; &quot;world&quot;&lt;/div&gt;');
// '<div>Hello & "world"</div>'

💡 Note: html-entities offers separate classes like XmlEntities, Html4Entities, and Html5Entities, while entities and he handle standards via options or built-in logic.

⚙️ Configuration and Control

How much control do you have over what gets encoded or decoded?

entities gives you granular control through options:

import { encode } from 'entities';

// Only encode non-ASCII characters
encode('café', { level: 'nonAscii' });
// 'caf&eacute;'

// Use XML-compatible encoding (no named entities)
encode('< &', { mode: 'xml' });
// '&lt; &amp;'

he focuses on strict HTML5 compliance but allows some decoding tweaks:

import * as he from 'he';

// Decode with strict mode (disallow ambiguous ampersands)
he.decode('AT&T', { strict: true });
// Throws error — 'AT&T' isn't a valid entity

// Default is lenient
he.decode('AT&T');
// 'AT&T'

html-entities lets you configure behavior at instantiation:

import { Html5Entities } from 'html-entities';

const entities = new Html5Entities({
  level: 'all', // or 'basic', 'nonAscii'
  encodeOptions: {
    useNamedReferences: false,
    decimal: true,
    hexadecimal: false
  }
});

entities.encode('©');
// '&#169;' instead of '&copy;'

This makes html-entities well-suited for scenarios where you reuse the same settings repeatedly—like in a server-rendered template engine.

📏 Supported Character Sets and Standards

Each library handles different sets of named entities:

  • entities supports XML, HTML4, and HTML5 via the mode option ('xml', 'html4', 'html5'). By default, it uses HTML5.
  • he strictly implements the HTML5 spec, including obscure and legacy entities. It’s known for its completeness and correctness.
  • html-entities provides distinct classes: XmlEntities (only &lt;, &gt;, etc.), Html4Entities, and Html5Entities, each with their own dictionary.

For example, the euro symbol :

// entities (default = HTML5)
encode('€'); // '&euro;'

// he
he.encode('€'); // '&euro;'

// html-entities (Html5Entities)
new Html5Entities().encode('€'); // '&euro;'

But if you use XmlEntities from html-entities, it won’t use &euro; (since XML doesn’t define it) and will fall back to numeric form if allowed.

🚀 Performance and Use Case Fit

  • entities is optimized for speed and small bundle size. It’s used internally by popular libraries like parse5 and cheerio. If you’re building a high-throughput SSR service or a static site generator, this is likely your best bet.
  • he prioritizes spec compliance over raw speed. It’s slower than entities but more accurate in edge cases involving ambiguous or malformed entities. Great for parsers, validators, or data cleanup tools.
  • html-entities trades a bit of performance for API flexibility. The class-based approach adds slight overhead but pays off when you need reusable, pre-configured encoders/decoders.

🛑 Error Handling and Edge Cases

How do they behave with malformed input?

  • entities decodes invalid entities as-is. decode('&xyz;') returns '&xyz;'.
  • he does the same by default but can be set to strict mode to throw on invalid entities.
  • html-entities always leaves unknown entities untouched—decode('&xyz;')'&xyz;'.

None of them attempt to “fix” broken markup beyond entity handling, which is correct behavior.

🌐 Browser and Node.js Support

All three work in both environments. None rely on DOM APIs, so they run cleanly in Node.js, Web Workers, or edge runtimes like Cloudflare Workers.

✅ Summary Table

Featureentitieshehtml-entities
API StyleFunctionalFunctionalClass-based (stateful instances)
Standards SupportXML, HTML4, HTML5 (via mode)HTML5 only (strictly compliant)Separate classes per standard
Config FlexibilityHigh (per-call options)Moderate (mainly for decoding)High (per-instance config)
PerformanceFastestSlower (accuracy-focused)Moderate
Best ForSSR, sanitization, parsersSpec-compliant tools, lintersTemplating, reusable processors

💡 Final Recommendation

  • Need speed and simplicity in a modern app? Go with entities.
  • Building a parser or validator that must follow HTML5 to the letter? Choose he.
  • Creating a templating system or editor where you’ll reuse the same encoding rules? html-entities’s instance-based API will feel natural.

All three are actively maintained and production-ready—so your choice should hinge on your project’s architectural needs, not fear of obsolescence.

How to Choose: entities vs he vs html-entities

  • entities:

    Choose entities if you need a fast, lightweight, and modern library that supports both encoding and decoding with fine-grained control over which character sets to process (e.g., XML, HTML4, HTML5). It’s ideal for performance-sensitive applications like SSR frameworks or sanitization pipelines where minimal bundle size and speed matter. Its API is clean and supports options like level and mode for precise behavior.

  • he:

    Choose he if you want a battle-tested, spec-compliant library that strictly follows the HTML5 standard for entity handling. It’s particularly strong in decoding accuracy and offers robust support for ambiguous ampersands and legacy named entities. Use it when correctness according to W3C specs is critical, such as in parsers, linters, or content migration tools.

  • html-entities:

    Choose html-entities if you prefer an object-oriented API with separate encoder and decoder instances that can be pre-configured for repeated use. It supports multiple standards (XML, HTML4, HTML5) and allows toggling features like decimal/hex numeric encoding. This package suits applications needing reusable, stateful entity processors—like templating engines or rich text editors—where configuration reuse improves ergonomics.

README for entities

entities NPM version Downloads Node.js CI

Encode & decode HTML & XML entities with ease & speed.

Features

  • 😇 Tried and true: entities is used by many popular libraries; eg. htmlparser2, the official AWS SDK and commonmark use it to process HTML entities.
  • ⚡️ Fast: entities is the fastest library for decoding HTML entities (as of September 2025); see performance.
  • 🎛 Configurable: Get an output tailored for your needs. You are fine with UTF8? That'll save you some bytes. Prefer to only have ASCII characters? We can do that as well!

How to…

…install entities

npm install entities

…use entities

const entities = require("entities");

// Encoding
entities.escapeUTF8("&#38; ü"); // "&amp;#38; ü"
entities.encodeXML("&#38; ü"); // "&amp;#38; &#xfc;"
entities.encodeHTML("&#38; ü"); // "&amp;&num;38&semi; &uuml;"

// Decoding
entities.decodeXML("asdf &amp; &#xFF; &#xFC; &apos;"); // "asdf & ÿ ü '"
entities.decodeHTML("asdf &amp; &yuml; &uuml; &apos;"); // "asdf & ÿ ü '"

Performance

Benchmarked in September 2025 with Node v24.6.0 on Apple M2 using tinybench. Higher ops/s is better; avg (μs) is the mean time per operation. See scripts/benchmark.ts to reproduce.

Decoding

LibraryVersionops/savg (μs)±%slower
entities7.0.05,838,416175.570.06
html-entities2.6.02,919,637347.770.3350.0%
he1.2.02,318,438446.480.7060.3%
parse-entities4.0.2852,8551,199.510.3685.4%

Encoding

LibraryVersionops/savg (μs)±%slower
entities7.0.02,770,115368.090.11
html-entities2.6.01,491,963679.960.5846.2%
he1.2.0481,2782,118.250.6182.6%

Escaping

LibraryVersionops/savg (μs)±%slower
entities7.0.04,616,468223.840.17
he1.2.03,659,301280.760.5820.7%
html-entities2.6.03,555,301296.630.8423.0%

Note: Micro-benchmarks may vary across machines and Node versions.


FAQ

What methods should I actually use to encode my documents?

If your target supports UTF-8, the escapeUTF8 method is going to be your best choice. Otherwise, use either encodeHTML or encodeXML based on whether you're dealing with an HTML or an XML document.

You can have a look at the options for the encode and decode methods to see everything you can configure.

When should I use strict decoding?

When strict decoding, entities not terminated with a semicolon will be ignored. This is helpful for decoding entities in legacy environments.

Why should I use entities instead of alternative modules?

As of September 2025, entities is faster than other modules. Still, this is not a differentiated space and other modules can catch up.

More importantly, you might already have entities in your dependency graph (as a dependency of eg. cheerio, or htmlparser2), and including it directly might not even increase your bundle size. The same is true for other entity libraries, so have a look through your node_modules directory!

Does entities support tree shaking?

Yes! entities ships as both a CommonJS and a ES module. Note that for best results, you should not use the encode and decode functions, as they wrap around a number of other functions, all of which will remain in the bundle. Instead, use the functions that you need directly.


Acknowledgements

This library wouldn't be possible without the work of these individuals. Thanks to

  • @mathiasbynens for his explanations about character encodings, and his library he, which was one of the inspirations for entities
  • @inikulin for his work on optimized tries for decoding HTML entities for the parse5 project
  • @mdevils for taking on the challenge of producing a quick entity library with his html-entities library. entities would be quite a bit slower if there wasn't any competition. Right now entities is on top, but we'll see how long that lasts!

License: BSD-2-Clause

Security contact information

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.

entities for enterprise

Available as part of the Tidelift Subscription

The maintainers of entities and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.