Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Purifier Laravel Package

larahook/purifier

Laravel wrapper for HTMLPurifier that cleans and sanitizes untrusted HTML before it reaches your views. Filter user-generated content through a simple, configurable API to strip XSS and other malicious markup while preserving safe formatting.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit larahook/purifier is a thin Laravel service-provider wrapper around ezyang/htmlpurifier: a container binding, a facade, and a publishable config file. Architecturally it slots into a conventional Laravel monolith at the request boundary (sanitize on write) or the render boundary (sanitize on read). Two fit caveats matter for planning: (1) HTMLPurifier is an HTML4/XHTML-era sanitizer and does not natively understand HTML5 elements (<figure>, <video>, data-*), so any product surface relying on modern markup needs custom config or will silently lose content; (2) it is a poor fit for API-only/headless services where sanitization is better owned by the consuming client or by a modern allowlist sanitizer. This is an infrastructure utility, not a differentiating capability — the opportunity score (35.5) is consistent with that: useful, low strategic leverage.

Integration feasibility Wiring is hours, not days: composer require, auto-discovery, php artisan vendor:publish, facade call. The real cost is policy, not plumbing — defining HTML.Allowed, attribute allowlists, and URI schemes is a security decision that needs review and a test corpus. Feasibility is high if the package installs cleanly on our Laravel/PHP matrix; that is unverified from the metadata.

Technical risk The dominant risk is supply chain, not code. Two stars and zero dependents means effectively no community scrutiny, no downstream issue triage, and no independent confirmation that the wrapper tracks Laravel's container/config changes across 9, 10, 11, and 12. Treat it as vendored code we own that happens to live on Packagist. Secondary risks: HTMLPurifier itself is mature but in low-maintenance mode (rare but real CVE cadence, with fixes landing upstream, not here); and performance is a known hazard — HTMLPurifier is DOM-based and can cost hundreds of milliseconds per large document if the definition cache is not configured correctly. The 2026-03-25 release date is encouraging for liveness but says nothing about breadth of testing.

Key questions

  • What are the exact composer.json constraints for laravel/framework, php, and ezyang/htmlpurifier? Does it install on our current Laravel and PHP 8.3/8.4?
  • Is this a fork of mews/purifier? If so, what changed, and why would we take the fork over the ~2k-star original?
  • Does it publish a config, register a Blade directive, and expose a clean()/purify() facade parity with upstream wrappers?
  • Does it configure the HTMLPurifier definition cache (filesystem/APCu) out of the box, or do we own that wiring?
  • Is there a CI matrix and test suite in the repo, or is it a config-and-provider stub?
  • Who on our side owns sanitization policy, and who is paged when upstream HTMLPurifier ships a CVE?

Integration Approach

Stack fit Fits a standard Laravel application on PHP 8.x. Verify against our actual framework version first — a Laravel 5-era wrapper may declare illuminate/support constraints that block install on 10/11/12, in which case we fork and bump constraints rather than downgrade the app.

Migration path If we are already on mews/purifier, the swap is a namespace change, facade alias update, and config diff — low mechanical cost, but re-run the sanitization contract tests because default configs differ. If we are greenfield, do not call the facade directly from controllers/models. Introduce an application-owned Sanitizer interface with a purify(string $html): string method and bind the package behind it. That single indirection lets us replace this package with Symfony's HtmlSanitizer (HTML5-aware, actively maintained) or a forked copy without touching call sites — the cheapest insurance available given the adoption profile.

Compatibility Two environment traps to design around: config publishing versus config:cache (published config must be static and committed, not generated at boot), and the definition cache path — in immutable/containerized deploys the cache directory must be created at image build or mounted writable, or HTMLPurifier falls back to its slow reparse path. Pin the exact package version and the underlying ezyang/htmlpurifier version; mirror both to an internal Composer registry so a yanked upstream release cannot break a deploy.

Sequencing

  1. Spike on a branch: install, publish config, measure p95/p99 latency on our worst-case payloads (long comments, pasted rich text, imported HTML).
  2. Draft the allowlist policy with security review; encode it as config plus a fixture corpus of XSS payloads and legitimate markup that must survive.
  3. Wrap behind the Sanitizer interface; write contract tests that run against the wrapper so a future swap is a config change.
  4. Enable in staging with logging of every stripped element/attribute; use that log to tune the allowlist before it becomes a user-visible content-quality complaint.
  5. Roll out; decide fork-and-own versus vendor-and-pin within the first month.
  6. Add the package to the dependency-review checklist so upstream releases and CVEs route to a named owner.

Operational Impact

Maintenance Assume we own it. Budget a pinned version, an internal mirror, a subscription to upstream HTMLPurifier releases, and a light quarterly review of the wrapper's Laravel compatibility. Realistic ongoing cost is low single-digit engineer-hours per quarter — until an upstream CVE forces a patch, at which point the wrapper's thinness is a benefit: we can bump ezyang/htmlpurifier in our fork without waiting for a maintainer.

Support No community to lean on: no issue triage, no Stack Overflow corpus, no downstream bug reports. Mitigate by keeping the wrapper's own surface small (provider + config) and relying on upstream HTMLPurifier's genuinely good documentation for policy questions. Ensure at least two engineers can read the config vocabulary; a single-owner bus factor here is a content-security risk.

Scaling Sanitization is CPU-bound and synchronous per request. Three levers, in order of value: sanitize-on-write for immutable content (comments, imported articles) so the cost is paid once; enable the definition cache so HTMLPurifier's grammar isn't rebuilt per process; cache purified output keyed by content hash for hot read paths. For bulk imports (legacy content migration, CSV/HTML uploads), move sanitization to a queue worker so it doesn't inflate request latency or trip PHP time/memory limits. Cap input size before the sanitizer — a multi-megabyte document will hurt regardless of configuration.

Failure modes

  • Unwritable definition cache → silent fallback to the slow path; latency regresses with no error. Alert on sanitize duration, not just on exceptions.
  • Over-sanitization (the most likely production incident): a config change or HTML5 gap silently strips legitimate markup — embeds, tables, footnotes. Users notice before monitoring does. The staging strip-log from step 4 is the control.
  • Encoding/entity drift: libxml version differences between base images can change parsing behavior across instances; pin the runtime image.
  • Malformed input exceptions bubbling to 500s on user-submitted content; wrap the call and fail closed to a plain-text escape rather than surfacing an error.
  • Config-cache mismatch after deploy leaving a stale allowlist live; include the published config in the deploy diff check.

Ramp-up Integration learning curve is roughly an hour for any Laravel developer. Policy authoring is the expensive part: HTMLPurifier's configuration vocabulary is idiosyncratic and under-documented for HTML5, so plan on half a day of focused work plus a written runbook covering the allowlist rationale, the definition-cache path, and the escalation path for upstream security releases. Given the package's adoption profile, the runbook is not optional — it is the primary control that makes a 2-star dependency operationally acceptable.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings