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

Laminas Feed Laravel Package

laminas/laminas-feed

laminas-feed is a PHP library for creating, reading, and validating RSS and Atom feeds. It offers parsers, writers, and feed classes with support for extensions like Dublin Core, iTunes, and Podcast, plus HTTP client integration for importing remote feeds.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. laminas/laminas-feed is a framework-agnostic Laminas component, not a Laravel package. It ships no service provider, no facade, no auto-discovery, and no config file, so adopting it in a Laravel codebase means owning a thin adapter layer ourselves. That is acceptable — the component does exactly one thing (parse and build RSS 0.9x/1.0/2.0 and Atom) and does it with a clean object model — but it must be planned as a wrapper effort, not a drop-in install. The good news is that its two halves have very different integration profiles: the Writer is effectively a self-contained XML builder (export() returns a string), and the Reader can consume a raw string via Reader::importString(), which lets us keep Laravel's HTTP client as the network layer instead of adopting laminas-http.

Integration feasibility. Feasible in a 1–2 sprint window for a first useful slice. The main friction points are:

  • Plugin managers. Both Reader and Writer route format and extension handling through Laminas' own plugin managers. These are PSR-11 aware (2.18.1 reworked them for psr/container:^2), so Laravel's container can bridge them, but they are not wired to the app container by default — we register instances explicitly in our own provider.
  • Dependency footprint. Expect laminas-stdlib, laminas-escaper, laminas-uri, laminas-validator, psr/container, and likely laminas-servicemanager. Not heavy, but it is a second DI paradigm sitting inside a Laravel app, and it will show up in audits and container-size conversations.
  • No Laravel-idiomatic ergonomics. Everything a modern Laravel developer expects (config publishing, response macros, queued job helpers, Feed::make()) we build and maintain.

Technical risk. Rated medium, with two genuinely material items:

  1. XML parsing of untrusted input. Feed consumption means parsing third-party XML on our infrastructure. We must explicitly confirm and pin down entity-loading and network-access protections (LIBXML_NONET, external entity resolution disabled, expansion limits) rather than assume them. Feed payload size caps and parse timeouts belong in our code, not the library's. This is the single item I would not sign off without a written test case.
  2. Upstream maintenance model. Laminas is volunteer-maintained with a security-team process but no commercial SLA, no LTS, and a small visible community (170 stars). Release cadence is genuinely healthy — PHP 8.5 support landed in 2.26.0, and PodcastIndex extension work continued through 2.26.x — which tells me maintainers are responsive to concrete use cases. But there is no support contract to buy, and a bus-factor conversation is legitimate for a component in a reader path.

Secondary risks: patch-level releases have carried compatibility adjustments before (2.18.1 was tagged as both bug and BC break), so we pin with ^2.26 and treat minors as reviewable, not automatic; and real-world feed malformation is a live source of bugs (2.26.1 fixed a UTF-8 encoding fallback, 2.13.1 changed invalid-date handling to throw an exception rather than return null) — these are exactly the edge cases our own consumers will hit.

Metadata caveats to validate before committing. Two fields in the supplied assessment look unreliable and should be re-checked against Packagist and GitHub directly: Dependents: 0 (implausible for a package that is the maintained successor to zendframework/zend-feed — likely a re-namespaced-package artifact of the data source), and the 2026-10-03 last-release date. I would not present either to stakeholders as-is. The opportunity: 70.3 score, if it means "room for an opinionated Laravel wrapper," matches my own read.

Key questions for the team before build:

  • Do we need a reader, a writer, or both? The business case changes materially. If we only publish feeds, the risk profile drops to near-zero — no untrusted XML parsing, no network, no rate limiting.
  • Does the product need podcast namespace support (iTunes, PodcastIndex live items, enclosures)? If yes, this library is a stronger fit than spatie/laravel-feed and is close to a differentiator. If no, the competitor is simpler and better known to Laravel devs.
  • What is our acceptable failure behavior when a remote feed is unreachable or malformed — drop the entry, show stale cache, or surface an error? The library throws; the product decision is ours.
  • Is a second DI container in-process acceptable to platform/security review, or is that a blocker?
  • Who owns the wrapper package, and what is its deprecation path if Laminas stalls?

Integration Approach

Stack fit. Requires PHP 8.1+ in practice (7.3 support was dropped at 2.18.0), which is compatible with Laravel 10/11 baselines. Install as laminas/laminas-feed:^2.26. Confirm "type": "library" in its composer manifest — it will not be auto-discovered, and that is intentional on our side: we want explicit registration, not magic.

Recommended shape. Build a small internal package (acme/laravel-feed) that owns the contract and keeps Laminas\Feed an implementation detail:

  • FeedServiceProvider registering singletons for the Reader/Writer entry points and the relevant plugin managers, with Laravel's container injected as the PSR-11 delegate.
  • config/feed.php: HTTP timeout, connect timeout, User-Agent, max payload bytes, per-host rate limit, cache TTL, allowed content types, sanitizer profile.
  • FeedResponseFactory: wraps the Writer's export() output into an Illuminate\Http\Response with the correct Content-Type (application/rss+xml; charset=UTF-8 / application/atom+xml), correct cache headers, and ETag/Last-Modified.
  • FeedFetcher: uses Http::withHeaders([...])->timeout(...)->get() then hands the body to Reader::importString(). This is the key architectural choice — it preserves Laravel's retry, middleware, telemetry, and test fakes, and avoids inheriting laminas-http semantics for our outbound traffic.
  • A FeedEntry DTO mapping Laminas' entry objects to a stable, narrow shape (id, title, url, published, summary, content, enclosure) so that swapping the parser later is a contained change.
  • Feed::fake() equivalent for tests, backed by a fixture corpus.

Migration path. Two likely entry points:

  • Greenfield publishing — go straight to the wrapper; no migration risk.
  • From SimplePie / spatie/laravel-feed / laravelium — migrate read paths first behind the DTO. Expect differences in HTML content sanitization, date parsing strictness, and how Atom <content> vs <summary> is selected (upstream fixed an Atom content regex as far back as 2.12.1). Migrate writers second; that is where namespace extensions give us a genuine capability upgrade and where output diffing against the legacy feed is a cheap, high-value validation step.

Compatibility notes.

  • Laravel's container implements PSR-11, so the plugin-manager bridge works; but Laminas' plugin managers are not Illuminate\Contracts\Container\Container-native, so avoid injecting Laminas internals into application code.
  • laminas-servicemanager will likely be present in vendor/ regardless of our preference. If its presence is a hard blocker for platform review, the fallback is a SimplePie-based build with reduced podcast capability — flag that tradeoff early rather than at the end.
  • Do not rely on laminas-http conditional GET (Reader::import($uri, $etag, $lastModified)); implement conditional requests with Laravel's client so all outbound HTTP traverses one observable path.

Sequencing (4 phases, ~4–6 weeks for one engineer):

  1. Spike (week 1). Reader + Writer against a fixture corpus of ~50 real feeds: large, malformed, non-UTF-8, podcast, Atom with XHTML content. Produce a written verdict on XXE/entity configuration and a payload-size/timeout policy. This is the go/no-go gate.
  2. Adapter core (weeks 2–3). Service provider, config, container bridge, FeedFetcher with conditional requests and caching, FeedResponseFactory, FeedEntry DTO, test fakes.
  3. Product surface (week 4). Controllers/routes or job classes as needed, Laravel cache and queue integration, per-host rate limiting, podcast/iTunes extension support if in scope.
  4. Hardening (weeks 5–6). Failure classification and metrics, load test on worst-case feed sizes, documentation and internal runbook, rollout behind a flag with the legacy path retained for one release.

Operational Impact

Maintenance. Ongoing cost is moderate but bounded, and mostly ours rather than upstream's. Upstream release cadence is healthy (~3 minor releases and 3 patches across the 2.24–2.26 window shown), so expect a handful of dependency bumps per year. Budget roughly 1–2 engineer-days per quarter for version tracking plus a recurring review of Laminas security advisories and their transitive dependencies (laminas-uri, laminas-validator have their own advisory history). The wrapper is the mitigation: if Laminas stalls or a serious advisory lands, we replace the internals behind FeedEntry/FeedResponseFactory without touching product code. I would treat that swap-ability as a hard acceptance criterion, not a nice-to-have.

Support. Documentation is genuinely good (docs.laminas.dev) — better than most packages in this niche — and issues get addressed (the PodcastIndex thread shows maintainers shipping community-requested extension work incrementally). But the support channel is GitHub issues on a volunteer schedule, with no SLA and thin Stack Overflow coverage for the Laminas namespace specifically. Internal knowledge will concentrate in whoever writes the adapter. Mitigations: the fixture corpus as executable documentation, a short internal runbook covering the top five failure modes, and a mandatory second reviewer on the wrapper package.

Scaling. Writer path scales trivially — it is string assembly, cacheable at the edge, no concern. Reader path is where the cost lives: DOM parsing is CPU- and memory-bound, and a 5 MB podcast feed with hundreds of entries is a real workload. Guidance:

  • Never parse a remote feed synchronously in a user request. Queue it, with per-feed locking so concurrent users do not trigger duplicate fetches.
  • Cache parsed results keyed by feed URL, honoring ETag/Last-Modified so most polls are 304s.
  • Enforce a max payload size and a parse timeout; reject rather than attempt.
  • Rate-limit per host — both for politeness and because some publishers will 429 or ban aggressive consumers. This is a reputational risk, not just a performance one.

Failure modes to design for explicitly:

Failure Symptom Mitigation
Malformed XML Parser exception Catch, classify, serve stale cache, alert on rate
Encoded/declared encoding mismatch Garbled text (see 2.26.1 fix) Pin UTF-8 handling; test non-UTF-8 corpus
Invalid date in entry Exception thrown, not null (behavior since 2.13.1) Per-entry try/catch; never fail the whole feed for one bad item
Oversized payload / entity expansion Memory or CPU exhaustion Hard byte cap, entity loading disabled, timeout
Redirect chains / 404 / 410 Silent staleness Explicit status handling; deactivate after N consecutive failures
Publisher schema drift Missing fields, truncated content DTO defaults; monitor field-null rates
Extension namespace not registered Fields silently absent Assert on expected namespaces in tests and at runtime

The "silently absent" class is the one I would emphasize: extension and namespace handling failing quietly is worse than throwing, because the product degrades without an alert. Instrument entry-count and field-population metrics per feed so degradation is visible.

Ramp-up. A Laravel developer new to Laminas needs roughly 1–2 days to be productive with the Reader/Writer object model, and closer to a week to be confident with plugin manager and extension registration — that is the genuinely unfamiliar part. Budget a day of pairing for the first person outside the adapter's author who has to touch it, and make sure at least two engineers can extend the fixture corpus. Compared with SimplePie (a weekend) or spatie/laravel-feed (an afternoon), this is a real but modest onboarding tax — justified only if podcast extensions or strict Atom fidelity are actually on the roadmap. If they are not, the honest recommendation is that this library is technically sound but operationally over-priced for what we would use it for, and a lighter alternative should win on total cost of ownership.

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.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc