isomorphic-dompurify

Isomorphic wrapper for DOMPurify that sanitizes HTML identically on server and client.

Library
npm
v4.1.0
596stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
80/100Excellent
Development Activity92
Maintenance100
Community40
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
65/100Good
Architecture78
Code Quality85
Innovation60
Learning Curve35

isomorphic-dompurify wraps DOMPurify, the widely used XSS sanitizer, so it can run identically in Node.js and the browser. On the server it lazily creates a jsdom window to give DOMPurify the DOM it needs; in the browser it defers directly to the native dompurify build via a bundler browser field remap and conditional exports, so client bundles never pull in jsdom.

The library re-exports the full DOMPurify API — sanitize, hooks, config, and TypeScript types — plus a callable default export that doubles as a factory for binding a DOMPurify instance to a specific window, useful in tests or sandboxed environments. A clearWindow() helper lets long-running Node processes periodically release the internal jsdom window’s accumulated DOM state to avoid progressive memory growth.

What You Get

  • Isomorphic sanitize() - the same API on server and client without branching your own code by environment
  • Full DOMPurify API surface - sanitize, addHook/removeHook/removeAllHooks, setConfig/clearConfig, isValidAttribute, isSupported, version, and removed are all re-exported
  • Callable factory default export - DOMPurify(window) binds a fresh instance to a specific window/JSDOM context, matching the underlying dompurify API
  • clearWindow() memory helper - releases jsdom’s internal DOM state in long-running Node processes to prevent memory growth
  • Full TypeScript type re-exports - Config, DOMPurify, and every hook type are re-exported so consumers don’t redeclare signatures

Common Use Cases

  • Sanitizing user-generated HTML before storing or rendering it in a Next.js, Nuxt, or Astro app that server-renders
  • Stripping XSS vectors (script tags, javascript: hrefs, inline event handlers) from CMS- or markdown-rendered content
  • Building framework-agnostic sanitization utilities shared between SSR and CSR code paths
  • Periodically clearing jsdom state in long-running Node services to prevent memory growth from repeated sanitize calls

Under The Hood

Architecture The package ships two nearly-symmetrical entry points — src/index.ts for Node and src/browser.ts for browsers — resolved automatically via package.json’s browser field remap and conditional exports (node vs default import/require), so consumers never branch on environment themselves. The Node entry lazily creates a module-level JSDOM window and DOMPurify instance, then wraps the DOMPurify handle in a JavaScript Proxy so that property access (DOMPurify.sanitize, addHook, etc.) always delegates to whichever purify instance is currently live — this is what lets clearWindow() swap out the jsdom window and DOMPurify instance in place without consumers re-importing anything. The browser entry skips jsdom entirely and just re-exports the native dompurify package directly, since a real DOM is already available. There’s no layering beyond this: the module is a single-file adapter with no internal abstractions, so what breaks if the core abstraction changes reduces to whether the Proxy’s get/apply traps stay in sync with whatever new methods a future dompurify release adds to its instance API.

Tech Stack Built in TypeScript targeting ES2020 with strict mode, bundled via tsup into dual CJS/ESM outputs (with .d.ts and .d.mts) for both the index and browser entries, externalizing dompurify and jsdom so they’re resolved from the consumer’s node_modules rather than bundled. Runtime dependencies are dompurify for the sanitizer itself and jsdom to supply a DOM on the server; devDependencies include Biome for linting and formatting, Vitest for testing, lefthook for git hooks, and pnpm as the package manager. The package pins a fairly recent Node engine range reflecting its jsdom major-version dependency, and CI (GitHub Actions) matrixes across multiple Node versions running lint, typecheck, build, and test on every push and pull request to master.

Code Quality Vitest tests cover all four public surfaces — default sanitize behavior, the callable factory export, a regression test pinned to a specific GitHub issue about jsdom node equality across separate JSDOM contexts, and a dedicated types test that exercises every re-exported hook and type against the runtime API to catch drift between the TypeScript declarations and dompurify’s actual behavior. Error handling is minimal by design since the module mostly delegates to dompurify and jsdom rather than implementing its own logic. Naming is consistent with the wrapped dompurify API so consumers transfer knowledge directly. Biome enforces lint and format rules, tsc —noEmit enforces type safety, and all checks run in CI across multiple Node versions — a small but well-guarded codebase.

API Design The library’s core ergonomic trick is a Proxy-wrapped default export that is simultaneously usable as a static-feeling object (DOMPurify.sanitize(…)) and as a factory (DOMPurify(window)) matching dompurify’s own callable-factory API, so switching between using the shared instance and binding to a specific window requires no import changes. Full re-export of DOMPurify’s hook and config types removes the need for consumers to redeclare signatures when typing hook callbacks, a small but real friction-reducer called out explicitly in the README. None of this is architecturally novel — isomorphic wrapper packages follow a well-worn shape the README itself credits as inspiration — but the clearWindow() memory-management escape hatch is a thoughtful, non-obvious addition addressing a real operational pain point that most naive DOMPurify-plus-jsdom wrappers don’t handle.

Used by 12 apps in this directory

TypeScript
98%
AGPL 3.0

Checkmate

Devops · Analytics · Monitoring

10,794

Self-hosted uptime and infrastructure monitoring with multi-protocol checks, global geo-coverage, and beautiful real-time dashboards.

View details
91
Repo Health
82
Technical
68
Dependency
Built with
TypeScript98%
Updated yesterday
TypeScript
97%
Other

Formbricks

Forms Surveys · Marketing · Analytics

12,897

Open-source experience management platform for in-app, website, email, and link surveys — privacy-first and fully self-hostable.

View details
93
Repo Health
81
Technical
70
Dependency
Built with
TypeScript97%
Updated yesterday
TypeScript
99%
AGPL 3.0

fountain-ink

Blogging

64

A self-hostable, decentralized blogging platform built on Lens Protocol — own your content, audience, and distribution forever.

View details
26
Repo Health
66
Technical
66
Dependency
Built with
TypeScript99%
Updated 7 months ago
Rust
67%
Other

GitButler

Developer Tools · Devops · AI Development

21,624

Git, but better — a modern version control client with stacked branches, parallel workflows, unlimited undo, and first-class support for AI-powered development.

View details
89
Repo Health
84
Technical
67
Dependency
Built with
Rust67%
TypeScript20%
Svelte11%
Updated yesterday
Python
67%
Apache 2.0

GPT Researcher

Productivity · AI Assistants

29,319

The pioneering open-source autonomous AI agent that conducts deep, multi-source research and produces citation-backed reports exceeding 2,000 words — faster and more reliably than any human researcher.

View details
90
Repo Health
91
Technical
63
Dependency
Built with
Python67%
TypeScript20%
Updated 1 weeks ago
TypeScript
97%
Other

Infisical

Security · Devops

29,145

The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.

View details
91
Repo Health
84
Technical
65
Dependency
Built with
TypeScript97%
Updated yesterday
Python
51%
AGPL 3.0

Khoj

AI Assistants · Knowledge Management · Productivity

37,160

A self-hostable AI second brain that chats with your documents, searches the web, builds custom agents, and runs entirely on your own LLM.

View details
75
Repo Health
82
Technical
69
Dependency
Built with
Python51%
TypeScript36%
Updated 1 months ago
TypeScript
64%
Other

NocoDB

No Code Platforms · Databases · Low Code Platforms

64,861

Turn any SQL database into a collaborative no-code spreadsheet with automatic REST APIs and real-time views.

View details
90
Repo Health
77
Technical
62
Dependency
Built with
TypeScript64%
Vue31%
Updated 2 days ago
TypeScript
81%
AGPL 3.0

OpenStatus

Monitoring · Devops

9,072

Open-source status pages and uptime monitoring with global synthetic checks, monitoring-as-code, and AI agent integration via MCP.

View details
77
Repo Health
82
Technical
69
Dependency
Built with
TypeScript81%
MDX15%
Updated yesterday

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search