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

Fast Image Size Laravel Package

marc1706/fast-image-size

Fast, dependency-free PHP library that reads image dimensions from file headers without loading the whole file, supporting JPEG, PNG, GIF, BMP, WebP, and more. A quick drop-in alternative to getimagesize for speed and low memory use.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit marc1706/fast-image-size is a framework-agnostic PHP utility, not a Laravel package — no service provider, facade, config, or published assets. That is a scoping fact the TPM should set expectations around: the library delivers a single capability (derive width/height/type from a local path or remote URL by reading header bytes only), and the integration surface — container binding, HTTP client wiring, cache adapter, SSRF guard — is work we own. Architecturally it is a thin, leaf dependency that slots behind an application service (ImageDimensionResolver / ImageDimensions) and does not constrain domain design. It fits naturally into media-ingestion jobs, URL import flows, and backfill commands. The correct framing to stakeholders is "small single-purpose dependency plus a thin adapter we maintain," not "install and configure a package."

Integration feasibility Low effort, high certainty. composer require marc1706/fast-image-size plus a PSR-18 client (Guzzle, already present in most Laravel stacks) and a Laravel-cache-backed adapter. Expected engineering effort is hours-to-a-day for the happy path; the real cost is policy work — host allow-listing, timeouts, retry budgets, cache TTL and invalidation. Delivery risk is concentrated in security review and test coverage, not in the library itself. Because it is a leaf dependency with a small API (one entry class), it can be adopted incrementally behind a feature flag rather than as a platform-wide commitment.

Technical risk

  • SSRF exposure (highest severity). Any user-supplied URL reaching this library inherits server-side request forgery risk. The library is not a security boundary; scheme/host allow-listing and private-IP blocking must live at our HTTP layer, and resolution-time IP checks must be enforced (a redirect to 169.254.169.254 is the classic failure). This requires application-security sign-off before any untrusted-URL surface ships.
  • Remote-server variance. Correctness depends on the origin honouring HEAD/range requests and returning accurate Content-Type/Content-Length. Misconfigured CDNs and hotlink protection yield inconsistent results — expect a long tail of "unknown dimensions" per origin rather than a clean pass/fail.
  • Silent failure semantics. The library returns null/false rather than throwing. Callers must handle "unknown" explicitly or we ship nulls and broken aspect ratios into the UI. This is a product decision (fallback strategy), not just an engineering one.
  • v1.3.1 behaviour change. Content is no longer enforced only on 200 responses, so non-200 responses carrying bytes are now parsed. This is a net win for 206 Partial Content (range requests are exactly the happy path) and signed-URL/redirect chains, and should reduce failed imports and support tickets. The corresponding risk: a 403/404/500 that happens to include bytes may now parse "successfully," so "probe succeeded" no longer implies "the URL is healthy." Any dead-link sweep, retry policy, or alerting that treats failure as a signal must instead validate HTTP status at our call site. Regression risk is low but the test matrix must explicitly cover 206, redirect, 404-with-body, and HTML error pages.
  • Dependency concentration. Single-maintainer project, infrequent releases, effectively zero dependents. Bus-factor risk is real but mitigated by the small API surface and cheap replacement path. v1.3.1 is a good illustration: a one-line-semantics patch that still warranted a changelog read and a regression test.

Key questions

  1. Which call paths accept untrusted URLs, and who signs off on the allow-list and private-IP-blocking policy before launch?
  2. Do we cache dimensions, with what TTL, and what is the invalidation story when an image is replaced at a stable URL?
  3. What timeout and retry budget per lookup, and does this run inline in a request path or exclusively in queued jobs?
  4. What is the product-defined fallback when dimensions are unknown — default aspect ratio, client-side measurement, or reject the asset?
  5. Do we pin ^1.3 now, and who owns the quarterly upstream review and the upgrade-as-tested-event cadence?
  6. Is format coverage adequate for our actual asset mix? AVIF/HEIC and animated-image frame data are not in scope here.

Integration Approach

Stack fit Works on any Laravel version on PHP 7.4+/8.x with Composer 2, with or without GD/Imagick (no extension requirement is a genuine deployment simplification for containerized or restricted environments). Pairs naturally with Guzzle for HTTP and Laravel's cache repository for the caching interface the library exposes. No queue, console, or asset-publishing integration beyond what we author. It belongs in the service layer and in jobs/Artisan commands for backfills — not scattered across controllers.

Migration path Greenfield adoption, no database or config migration. Install, bind the HTTP client and cache adapter in a MediaServiceProvider, wrap in one resolver service with a single method (dimensionsFor(string $url): ?array), and expose that as the only entry point. If we currently call getimagesize() on already-downloaded files, this is a drop-in replacement for the remote-URL case only — local files should stay on native functions, which are faster and carry no network dependency. Backfilling width/height/type columns across an existing S3/CDN/legacy library is cheap enough to run as a batch job and is a strong candidate for an early, visible win.

Compatibility v1.3.1 is backwards compatible; no API surface was removed. Our integration must not depend on the prior "only 200" behaviour in either direction, and anything that infers URL health from probe success must be refactored to check status explicitly. Pin to ^1.3 and treat minor upgrades as deliberate, tested events — not automatic merges — given the single-maintainer cadence.

Sequencing

  1. Add the dependency and bind Guzzle + cache adapter behind our own interface.
  2. Implement the resolver service with allow-listing, timeouts, explicit null-handling, and status-code validation at the call site.
  3. Build the test safety net with a mocked PSR-18 client covering 200, 206, redirect chains, 404/503, HTML-body responses, and truncated/oversized payloads — this is the regression guard for the v1.3.1 semantics.
  4. Application-security review of the untrusted-URL posture before any external-input surface goes live.
  5. Roll out behind a flag to a single low-risk surface (e.g. link previews or backfill) before adopting it for user-facing media metadata.
  6. Extend to media ingestion, aspect-ratio storage, and CLS-safe <img> sizing once the resolver's miss rate is understood in production.

Operational Impact

Maintenance Low code footprint, low ongoing cost — but a single-author dependency with infrequent releases means bus-factor risk is the primary maintenance concern. Mitigation: keep the wrapper thin enough that replacement is a day's work; getimagesize() on a ranged download and a Guzzle-based header parse are both credible fallbacks. Budget a light quarterly upstream review; the v1.3.1 patch is exactly the kind of small change that still deserves a changelog read. Total cost of ownership is effectively the cost of the adapter we write, not the library.

Support Failures present as "dimensions unknown," surfacing as missing aspect ratios or placeholder sizing rather than exceptions — so support burden lands on the feature owner, not infrastructure, and rarely escalates to an incident. Document the null contract explicitly and ship a product-defined fallback (default aspect ratio, lazy client-side measurement) so a resolver miss is a degraded experience. The expected v1.3.1 benefit — fewer false negatives against CDNs, object stores, and signed URLs returning 206 — should measurably reduce "could not determine image size" tickets on import flows. The trade-off is that a dead-link cleanup or retry workflow keyed on probe failure will silently stop working; that logic must move to explicit status checks, and the owning team should be told so.

Scaling Cost is network egress and latency, not CPU — each lookup is one or more outbound HTTP requests reading a few hundred bytes. At volume, cache aggressively keyed on URL, prefer queueing for bulk imports and backfills, and add a per-host concurrency cap plus a circuit breaker so a slow or hostile origin cannot exhaust PHP-FPM workers. Caching also materially reduces blast radius when an upstream origin goes dark, and keeps lookups off the synchronous request path wherever possible.

Failure modes

  • Origin ignores range/HEAD → full download or null; watch egress and add per-lookup byte caps.
  • Origin returns an HTML error page → must be rejected; the v1.3.1 relaxation makes this the primary regression to verify in test and in a canary.
  • Redirect to an internal address → SSRF; enforce IP checks at resolution time, not just on the initial URL.
  • Timeouts under load → cascading latency in synchronous paths; keep lookups in jobs.
  • Stale cache after replacement at a stable URL → wrong dimensions persisted; provide a manual invalidation hook.
  • Upstream abandonment → no security patches; the thin wrapper is the contingency.

Ramp-up A mid-level Laravel engineer can own this in under a day: the library is one class, and the surrounding work (DI bindings, Guzzle config, cache adapter, SSRF guard) uses patterns already established in the codebase. The genuinely non-obvious areas are PSR-18 client wiring and the untrusted-URL security posture, which application security should review before the first external-input surface ships. Plan for roughly one engineer-day of build, a half-day of security review, and a half-day of test authoring around the 206/error-body matrix — a small, low-risk increment that unblocks media metadata, URL import, and aspect-ratio-driven rendering work.

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