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

Markdown Dom Laravel Package

prinsfrank/markdown-dom

prinsfrank/markdown-dom is a PHP package that converts Markdown into a DOM structure, letting you traverse, query, and manipulate parsed Markdown programmatically before rendering. Useful for custom transformations, content processing, and DOM-based workflows.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Feature enablement — structured content, not string manipulation. The package parses Markdown into a DOM tree (document → block/inline nodes → text) rather than returning an HTML string. That unlocks product features that are painful with regex over HTML: auto-generated tables of contents, external-link hardening (rel="nofollow"/target="_blank"), lazy-loaded and CDN-rewritten images, responsive table wrappers, content excerpts for index pages, and multiple output formats (HTML + plain text + search index) from a single parse.
  • Build vs. buy for Markdown handling. Buying this removes a custom Markdown-to-tree implementation from our backlog. But it is only half a solution: markdown-dom defines the DOM and a MarkdownParser contract; it ships no parser of its own. The practical dependency is an adapter such as markdown-dom-league-common, which wraps league/commonmark — already a transitive dependency of Laravel's Markdown mail. So the real decision is "adopt a thin node abstraction on top of a parser we already run," which is a much smaller commitment than adopting a new parser.
  • Roadmap gating — do not make this the default renderer. For the common case (Markdown in, HTML out), Laravel 9+ already offers Str::markdown() in one line. This package earns its place only on surfaces that need structural traversal. Roadmap sequencing should reflect that: pilot on low-blast-radius surfaces (internal docs, changelog pages, comment bodies) behind an application-owned MarkdownRenderer interface, and promote to default only after output parity against the incumbent on a real content corpus.
  • Architecture and upgrade-freedom decisions. There is no Laravel coupling — no service provider, config, facade, or Blade integration — meaning it will not pin illuminate/* ranges or constrain framework upgrades. That is a plus for longevity, but every bit of wiring becomes ours to own, so the PM cost is a small, permanent internal abstraction rather than a one-off integration.
  • Platform and cost decisions. It requires PHP 8.x and ext-dom. DOM construction and serialization are materially heavier in CPU and memory than string-based rendering. This is irrelevant if rendering happens once at write time with cached HTML, and potentially relevant if user content is rendered on every request — a product/infra decision about where rendering sits in the request path.
  • Risk posture for early adoption. At v0.2.x, single maintainer, 0 stars and 0 dependents, the package is pre-1.0 and unvalidated by any external community. SemVer permits breaking changes in minor bumps on the 0.x line. The PM decision this supports is "pin exactly, wrap in an interface, assume we may swap it out."
  • Security scope. Sanitization is not included. Markdown permits raw HTML depending on the parser's html_input setting, and the DOM faithfully represents whatever the parser produced. For any user-authored content, sanitization must be an explicit, separately-resourced work item — not inferred from the parser.

When to Consider This Package

Consider it when:

  • You need to inspect or transform Markdown-derived content structurally — TOC extraction, link/image rewriting, excerpt generation, content analysis, or emitting several formats from one parse — and you are currently regex-hacking HTML strings.
  • You want a small, focused node abstraction layered on top of league/commonmark rather than building your own AST handling.
  • You value framework-agnosticism and want a dependency that will not constrain Laravel upgrades.
  • You can isolate it behind an application-level interface and can accept version pinning plus a golden-file test suite as part of the cost of adoption.
  • Rendering happens at write time (parse on save, cache the HTML), which neutralizes the performance concern.

Look elsewhere when:

  • You only need Markdown → HTML. Str::markdown() is one line, already uses league/commonmark, and adds no dependency — use it.
  • You need a mature, widely adopted parser with a large extension ecosystem, GFM tables/footnotes/task lists proven out of the box, CommonMark conformance guarantees, or vendor support. Go straight to league/commonmark or an equivalent established parser.
  • You need mission-critical content pipelines with an SLA. Bus factor here is 1, with no BC policy published for the 0.x line.
  • Round-tripping (Markdown → DOM → Markdown) is required; that capability is unverified.
  • You cannot fund sanitization and golden-file testing as first-class work. The package does not sanitize, and unsupported syntax will drift silently — golden-file tests are the only thing that catches it.
  • You need the DOM on every request at scale, with no caching layer available.

Gating questions before any adoption decision: Which Markdown dialect and extension set does it target? Is the custom autoloader on the Composer consumer path or only in the dev harness (i.e., could the v0.2.1 bug ever have reached us)? Is DOMDocument configured against XXE and entity expansion for untrusted input? What is the maintainer's release cadence and BC stance for 0.x? Do we need anything beyond HTML output?

How to Pitch It (Stakeholders)

To executives (one paragraph): This is a small, MIT-licensed PHP library that turns Markdown into a structured document tree instead of an HTML string, which lets us build content features we currently can't do without brittle string manipulation — auto-generated tables of contents, safer external links, image handling, list-page excerpts, and multiple output formats from a single parse. It does not replace our Markdown parser; it sits on top of the one Laravel already ships with, so the incremental technical commitment is small. The trade-off is maturity: version 0.2.1, one maintainer, no external adopters yet. Recommendation is a contained pilot on internal, low-risk surfaces behind our own interface — roughly half a day to integrate, one to two more days for test coverage and sanitization — with a decision to broaden at 1.0 or once output parity is demonstrated. If the pilot disappoints, swapping back is a one-class change.

To engineering: markdown-dom is the DOM abstraction, not a parser — a fresh install that "does nothing" is a missing adapter (markdown-dom-league-common) or an unbound MarkdownParser interface. Bind the parser in a service provider and route rendering through a single Blade component so {!! !!} stays confined to one audited place. Parse on save and persist the HTML; if rendering on read is unavoidable, cache keyed on the Markdown plus serialized parser config and bust on deploy. Do the high-value work in a node visitor — link hardening, image lazy-loading/rewriting, heading collection for TOCs, block-level excerpts — and express extensions through league/commonmark config rather than post-processing HTML. Assert against the tree in tests, not rendered strings, and add a golden-file suite over 50–100 real documents before promoting this past the pilot. Sanitization is ours to implement: set html_input => 'strip' and allow_unsafe_links => false, and add a DOM whitelist or HTMLPurifier for user content.

Release note (v0.2.1): A single patch fixing an off-by-one error in the package's bundled custom autoloader (PR #18). No new features, no deprecations, no breaking changes, no migration steps. Anyone on 0.2.0 should upgrade — a broken autoloader surfaces as intermittent class-not-found errors that masquerade as Composer cache problems — then run composer dump-autoload and re-check any vendored or copied classes. It slightly improves the maintenance signal and mildly flags that the package still carries hand-rolled loading logic; it does not alter the adoption assessment. Pin the version (0.2.1 or a narrow range) rather than a bare ^0.2.

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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style