entities、he 和 html-entities 都是用于处理 HTML 实体(如 &、<、— 等)的 JavaScript 库,主要功能包括将 HTML 实体解码为原始字符(decode),或将特殊字符编码为实体(encode)。它们广泛应用于富文本编辑器、模板引擎、XSS 防护、内容清洗等场景。这些库在 API 设计、功能覆盖、默认行为和可配置性方面存在显著差异,直接影响开发效率和运行时行为。
在前端开发中,处理用户输入、渲染富文本或防止 XSS 攻击时,经常需要将特殊字符转为 HTML 实体(如 < → <),或将实体还原为原始字符(如 © → ©)。entities、he 和 html-entities 是三个主流解决方案,但它们在设计理念、API 风格和行为细节上差异显著。本文从实战角度剖析三者异同,助你做出精准选型。
三者都提供 encode 和 decode 功能,但调用方式和默认行为不同。
entities 采用函数式风格,所有操作通过顶层函数完成:
import { encode, decode } from 'entities';
const encoded = encode('<div>© 2024</div>');
// '<div>© 2024</div>'
const decoded = decode('<div>© 2024</div>');
// '<div>© 2024</div>'
he 同样使用函数式 API,但方法名略有不同:
import { encode, decode } from 'he';
const encoded = encode('<div>© 2024</div>');
// '<div>© 2024</div>'
const decoded = decode('<div>© 2024</div>');
// '<div>© 2024</div>'
html-entities 则要求先创建特定类型的实体处理器实例:
import { Html5Entities } from 'html-entities';
const entities = new Html5Entities();
const encoded = entities.encode('<div>© 2024</div>');
// '<div>© 2024</div>'
const decoded = entities.decode('<div>© 2024</div>');
// '<div>© 2024</div>'
💡 注意:
html-entities还提供AllHtmlEntities、XmlEntities、SvgEntities等类,分别对应不同规范。
当输入包含不完整或非标准实体时,三者表现迥异。
考虑以下畸形输入:'foo & bar'(缺少分号)。
entities 默认严格遵循规范,不会将其视为实体:
import { decode } from 'entities';
decode('foo & bar'); // 'foo & bar'(原样保留)
he 模拟浏览器行为,在宽松模式下会尝试修复:
import { decode } from 'he';
decode('foo & bar'); // 'foo & bar'(自动补全)
html-entities 行为取决于所选类,Html5Entities 默认也较宽松:
import { Html5Entities } from 'html-entities';
new Html5Entities().decode('foo & bar'); // 'foo & bar'
这种差异在处理用户粘贴的富文本时尤为关键 —— 若内容来自 Word 或旧系统,常含不规范实体,此时 he 或 html-entities 的容错能力更可靠。
三者均支持选项配置,但粒度和方式不同。
假设只想编码 <, >, &, ",而不碰其他字符(如 ©):
entities 通过 level 选项实现:
import { encode } from 'entities';
encode('© <script>', { level: 'basic' });
// '© <script>'(仅基础字符被编码)
he 使用 useNamedReferences 和 encodeEverything 等选项组合:
import { encode } from 'he';
encode('© <script>', {
useNamedReferences: true,
encodeEverything: false
});
// '© <script>'
html-entities 在实例化时传入选项:
import { Html5Entities } from 'html-entities';
const encoder = new Html5Entities({
encodeEverything: false,
useNamedReferences: true
});
encoder.encode('© <script>'); // '© <script>'
在 HTML 属性中,' 可表示为 ',但在文本节点中可能无需处理。he 提供 isAttributeValue 选项:
import { decode } from 'he';
// 属性值上下文
decode('It's OK', { isAttributeValue: true }); // "It's OK"
// 文本上下文
decode('It's OK', { isAttributeValue: false }); // "It's OK"(不变)
而 entities 和 html-entities 无此细分,统一按标准解码。
对于十进制(—)或十六进制(—)实体:
entities 默认解码所有数字引用,可通过 scope: 'strict' 限制。he 总是解码合法数字引用,行为与浏览器一致。html-entities 在 Html5Entities 下同样完全支持。// 所有库均能正确处理
'—' → '—'(em dash)
'—' → '—'
但若输入非法数字(如 � 超出 Unicode 范围):
entities 返回空字符串或替换字符(取决于选项)。he 返回原始字符串(不处理)。html-entities 抛出错误或返回原始字符串(视版本而定)。建议在处理不可信输入时,先验证再解码,避免意外行为。
| 维度 | entities | he | html-entities |
|---|---|---|---|
| API 风格 | 函数式,简洁 | 函数式,选项丰富 | 面向对象,需实例化 |
| 默认宽容度 | 严格(符合规范) | 宽松(模拟浏览器) | 中等(HTML5 类较宽松) |
| Bundle Size | 最小 | 中等 | 较大(多类导出) |
| 典型用途 | 现代 SPA、轻量级编码 | UGC 内容解析、高容错场景 | SSR、服务端长期任务 |
entities:若你控制输入源(如内部 CMS),且追求最小依赖,entities 的简洁性和性能优势明显。he:当内容可能含畸形实体(如从邮件、Word 复制),he 的浏览器兼容性可减少显示异常。html-entities:若需在多个地方使用相同编码规则(如同时处理 HTML 和 XML),其实例化模式便于封装。无论选择哪个库,请始终记住:实体编码不是 XSS 防护的万能药。对于动态插入 HTML 的场景,应优先使用 textContent 或安全的 DOM API,而非依赖手动编码。
选择 entities 如果你需要一个轻量、高性能且专注于核心实体转换的库。它提供统一的 decode 和 encode 接口,支持 XML、HTML4、HTML5 多种模式,并允许通过选项精细控制是否处理数字引用、命名引用或特殊字符。适合对 bundle size 敏感或需要明确控制解析行为的现代前端项目。
选择 he 如果你希望获得最接近浏览器原生行为的 HTML 实体解码能力,尤其是处理边缘情况(如不完整或畸形实体)时。he 的 decode 方法默认更宽容,能正确还原大量非标准输入,且支持自定义解码选项(如 isAttributeValue)。适合内容来自不可信来源、需高容错解析的场景,如用户生成内容(UGC)展示。
选择 html-entities 如果你需要面向不同上下文(HTML、XML、SVG 等)的专用编码/解码器实例,并偏好面向对象的 API 风格。该库通过 Html5Entities、XmlEntities 等类提供预配置的转换器,适合服务端渲染或需要复用相同配置的长期任务。但注意其 API 较冗长,不适合轻量级前端使用。
Encode & decode HTML & XML entities with ease & speed.
entities is used by many popular libraries; eg.
htmlparser2, the official
AWS SDK and
commonmark use it to process
HTML entities.entities is the fastest library for decoding HTML entities (as of
September 2025); see performance.entitiesnpm install entities
entitiesconst entities = require("entities");
// Encoding
entities.escapeUTF8("& ü"); // "&#38; ü"
entities.encodeXML("& ü"); // "&#38; ü"
entities.encodeHTML("& ü"); // "&#38; ü"
// Decoding
entities.decodeXML("asdf & ÿ ü '"); // "asdf & ÿ ü '"
entities.decodeHTML("asdf & ÿ ü '"); // "asdf & ÿ ü '"
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.
| Library | Version | ops/s | avg (μs) | ±% | slower |
|---|---|---|---|---|---|
| entities | 7.0.0 | 5,838,416 | 175.57 | 0.06 | — |
| html-entities | 2.6.0 | 2,919,637 | 347.77 | 0.33 | 50.0% |
| he | 1.2.0 | 2,318,438 | 446.48 | 0.70 | 60.3% |
| parse-entities | 4.0.2 | 852,855 | 1,199.51 | 0.36 | 85.4% |
| Library | Version | ops/s | avg (μs) | ±% | slower |
|---|---|---|---|---|---|
| entities | 7.0.0 | 2,770,115 | 368.09 | 0.11 | — |
| html-entities | 2.6.0 | 1,491,963 | 679.96 | 0.58 | 46.2% |
| he | 1.2.0 | 481,278 | 2,118.25 | 0.61 | 82.6% |
| Library | Version | ops/s | avg (μs) | ±% | slower |
|---|---|---|---|---|---|
| entities | 7.0.0 | 4,616,468 | 223.84 | 0.17 | — |
| he | 1.2.0 | 3,659,301 | 280.76 | 0.58 | 20.7% |
| html-entities | 2.6.0 | 3,555,301 | 296.63 | 0.84 | 23.0% |
Note: Micro-benchmarks may vary across machines and Node versions.
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
entitiesinstead 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
entitiessupport 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.
This library wouldn't be possible without the work of these individuals. Thanks to
he, which was one of the inspirations
for entitiesparse5 projecthtml-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
To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.
entities for enterpriseAvailable 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.