DOMPurify
What is DOMPurify
DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML, and SVG. It is written in JavaScript, MIT licensed, and available on npm as dompurify with TypeScript types bundled directly in the package (no separate @types install required). Currently at v3.x, it sees ~8M weekly npm downloads and has ~14k GitHub stars. DOMPurify runs in the browser using the native DOM parser, and can also run on Node.js via a jsdom or linkedom adapter. It is maintained by Cure53, a Berlin-based security research firm.
Why we recommend it
- Prevents XSS from user-supplied HTML — whenever you render HTML from a rich-text editor, a markdown pipeline, or an external API, DOMPurify strips malicious scripts, event handlers, and dangerous elements before the content ever touches the DOM.
- Battle-tested by security experts — Cure53 has a strong track record of responsible disclosure, ongoing audits, and rapid response to reported vulnerabilities.
- Framework-agnostic — works alongside React, Vue, Astro, or plain JavaScript with no framework-specific adapter required.
- Tiny and fast — ~7 kB minified + gzipped. Uses the browser's own HTML parser, so parsing is native-speed with no regex heuristics.
- Simple API — a single call,
DOMPurify.sanitize(dirtyHTML), returns a clean HTML string safe forinnerHTMLor React'sdangerouslySetInnerHTML. - TypeScript-ready — types are bundled directly in the
dompurifypackage; no separate@typesinstall needed. - Configurable — allow-lists and deny-lists for tags and attributes let you tighten or relax the default rules to match your content policy.
- Fits the Aliz stack — pairs directly with React's
dangerouslySetInnerHTMLpattern for safe rich-text rendering.
When to use
- Rendering HTML from rich-text editors such as TipTap, Quill, or Draft.js
- Displaying markdown-to-HTML output produced by libraries like marked or remark
- Rendering HTML content sourced from external APIs, a CMS, or user submissions
- Any use of
dangerouslySetInnerHTMLin React where the content is not fully developer-controlled
When NOT to use
- Static, developer-controlled HTML — if there is no user input and no external content, sanitization adds overhead with no security benefit.
- Plain-text content — React's default rendering and
textContentalready escape HTML. Sanitization is only needed when you are deliberately injecting raw HTML. - Primary server-side sanitization — DOMPurify is designed for the browser. On Node.js it requires a jsdom or linkedom adapter, which adds complexity and overhead. For sanitizing content before persisting it to a database, prefer a server-side library purpose-built for that environment.
Why over alternatives
- vs sanitize-html — sanitize-html is Node.js-first and regex-based, making it slower and larger in the browser. DOMPurify uses the native DOM parser, is significantly faster, has a smaller footprint, and has a stronger security track record. Prefer sanitize-html only when you need server-side sanitization without a DOM environment.
- vs xss (js-xss) — DOMPurify has broader, more consistent browser support, is maintained by dedicated security researchers, and offers a more thorough and configurable sanitization model.
- vs manual sanitization — never roll your own HTML sanitizer. Custom regex or string-manipulation approaches are fragile and routinely bypassed by novel XSS payloads. Always use a dedicated, audited library.
dangerouslySetInnerHTML without sanitization is a common XSS vectorPassing unsanitized user content directly to dangerouslySetInnerHTML is one of the most frequent XSS mistakes in React applications. Always run the HTML through DOMPurify.sanitize() first:
import DOMPurify from 'dompurify';
function RichTextContent({ html }) {
return (
<div
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }}
/>
);
}
Resources
- Official DOMPurify GitHub
- npm package
- Cure53 security advisories
- React docs on dangerouslySetInnerHTML
- React — the UI framework DOMPurify pairs with for safe rich-text rendering