spatie/statamic-responsive-images
Spatie's Responsive Images addon for Statamic CMS generates responsive image versions automatically, with a fieldtype for art direction and Glide presets driven by configurable breakpoints.
Architecture fit
This is not a general-purpose Laravel package; it is a Statamic CMS addon with a hard Statamic 4.0+ constraint. It extends Statamic's asset container model and Glide pipeline rather than introducing an independent imaging service, which makes it an excellent fit only if Statamic is already the content backbone. In a plain Laravel or headless-API-only product without Statamic, the package delivers zero value and should be rejected at triage. Where Statamic is present, the fit is tight: it ships a Control Panel fieldtype for art direction, an Antlers {{ responsive:* }} tag, a Blade directive, and a GraphQL augmentation path, so it covers both server-rendered and headless delivery from one dependency. The important architectural caveat is that the package generates its own derivative presets and explicitly does not use your project's Glide presets — if the product already has a curated Glide preset catalogue, this creates a second image pipeline that must be governed deliberately.
Integration feasibility
Low effort. composer require, publish config/views, add a fieldset YAML block, and reference the tag in templates. There is no new infrastructure to stand up beyond what Statamic already needs (PHP image driver, Glide cache, optional queue). The GraphQL surface is a genuine feasibility win for headless consumers — arguments mirror tag parameters with colons replaced by underscores, and the fieldtype augments itself without arguments. Realistic estimate for a Statamic-fluent developer: well under a day to first successful render, with the bulk of effort going into breakpoint/format/quality policy rather than the plumbing.
Technical risk
v2.11.0 "Fix Statamic 3.3 support", dropping 3.1/3.2), so this dependency sits on the critical path of every CMS upgrade.statamic.assets.image_manipulation.cache = false, but the responsive:regenerate command only works when that value is true. In the recommended configuration there is no supported bulk-regeneration path — derivatives are lazily created on first browser request. That is a real operational constraint, not a footnote.src saving as an array, AVIF leaking into <img> attributes, float-to-int conversions, forced absolute URLs, upscaling. Individually minor; collectively a signal that the HTML/Antlers surface is where defects concentrate. Pin versions and snapshot rendered markup in tests.APP_DEBUG is false." Degradation is therefore invisible to users but also invisible to alerting unless logs are monitored — an observability gap we must close ourselves.sizes. The tag uses JavaScript to compute the sizes attribute. This is an opinionated design that affects no-JS rendering, first-paint selection, and layout stability; it should be validated against our performance budget rather than accepted implicitly.Key questions
image_manipulation.cache mode do we choose, and how do we regenerate derivatives given the documented command constraint?Stack fit
The package assumes Laravel + Statamic + Glide + Antlers (or Blade, or GraphQL). Its default breakpoints are TailwindCSS's, which is a strong alignment if the frontend already uses Tailwind — otherwise we must override the breakpoints array in responsive-images.php and keep it synchronised with the design system's tokens. Format policy (WebP/AVIF) and quality values are configurable globally with per-breakpoint tag overrides, so the pipeline can be tuned without code changes, which is the right shape for a TPM-owned configuration surface.
Migration path
There is no backfill. Existing assets gain responsive variants lazily, on first request, which means a migration produces a cold-start window on high-traffic pages. The pragmatic sequence is: ship the config and templates behind a feature flag on low-traffic templates, let the queue warm derivatives during off-peak, then expand. If bulk pre-generation is judged necessary, flipping image_manipulation.cache to true unlocks php please responsive:regenerate — but that reverses the package's own recommendation and materially changes storage and CPU profiles, so it must be a deliberate, documented decision with a rollback. Note also that the fieldtype's asset-reference updating (added in v2.14.0) means migrating existing image fields to the responsive fieldtype needs a content migration and a verification pass on rename/relink behaviour.
Compatibility
Statamic 4.0+ is the only hard version gate stated. PHP minimum, Statamic minor compatibility, and image-driver support for AVIF are not stated in the README and must be confirmed against composer.json and CI before committing. The Control Panel fieldtype is a compiled Vue component that has required re-ships (v2.13.1, v2.14.3) — pin an exact version and smoke-test the CP field UI after every bump, since editor-facing breakage is the highest-visibility failure mode. Coordinate with the team on the GraphQL schema additions (responsive field on assets and fieldtype augmentation) if a mobile or headless client consumes the API, as these are additive but schema-visible.
Sequencing
image_manipulation.cache mode and the derivative storage/CDN target; write it into the runbook.responsive-images.php queue key and excluded_containers list match our topology.sizes behaviour with JS disabled.Maintenance MIT-licensed, forkable, and from a reputable vendor, but maintained as open source with no SLA. The release history is a steady stream of small patches, which is healthy activity but also means "upgrade and read the changelog" is a recurring chore. Assign explicit ownership: one engineer accountable for Statamic upgrades, one for the image/asset pipeline config. Budget a few hours per Statamic minor and per package minor for regression review of rendered markup. Because the package owns its own presets, keep a written record of the chosen breakpoints/quality/format policy so it can be reproduced if we ever need to fork or replace it.
Support Community issue tracker plus a security contact at the vendor. No contractual response time. If image delivery is business-critical (e-commerce hero imagery, editorial front pages), the absence of an SLA should be an accepted, recorded risk — the vendor's paid support products are the natural mitigation. Internal ramp-up is small: a Statamic-fluent developer is productive within a day, and the README covers fieldtype config, tag parameters, breakpoints, Glide passthrough, HTML attributes, view publishing, and GraphQL, which is unusually complete for an addon of this size.
Scaling The dominant cost is derivative generation — CPU and memory bound, not request bound — so a queue worker is effectively mandatory at any real traffic level. Storage growth depends entirely on the cache-mode decision and on how many breakpoint × format × ratio combinations the templates request; the combination space grows multiplicatively and is easy to inflate accidentally with per-template art direction. Put a CDN in front of the Glide URLs so derivative creation is a one-time cost per asset-variant, and monitor the first-hit latency tail after content publishes. The base64 placeholder adds inline page weight on every image and should be disabled on listing pages if the performance budget is tight.
Failure modes
APP_DEBUG=false; users see degraded rendering with no signal. Build a log-based alert.src typing, stray format attributes, absolute vs relative URLs, upscaling — mean rendered HTML is the fragile surface. Snapshot tests on the image templates are cheap insurance.Ramp-up
Days, not weeks, for the backend; the real work is cross-functional. Frontend must own the breakpoint and sizes contract, content/editorial must be walked through the new art-direction fieldtype (including per-breakpoint source overrides), and ops must own queue health, derivative storage, CDN behaviour, and the cache-mode decision. Recommend: a two-week pilot on a single template with an explicit exit criterion (performance budget met, no markup regressions, editor workflow accepted), followed by a go/no-go on broader adoption and version pinning as a platform dependency.
How can I help you explore Laravel packages today?