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

Laravel Image Laravel Package

folklore/laravel-image

A Laravel image package that simplifies common image workflows with a clean API for resizing, cropping, and generating thumbnails while integrating with Laravel’s filesystem and configuration. Useful for handling uploaded images and model attachments in apps.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The 2.x line is a re-architecture of the package around explicit contracts rather than a bag of helpers, and that is the most important fact for planning. The public surface is now: an immutable PendingImage builder (Image::for($ref)->preset(...)->signed(...)->url()), a config file (config/image.php) that owns presets, versions, signing keys, hosts, limits and delivery policy, and a set of named contracts — ImageSpec, UrlCodec, Signer, SourceResolver/ImageSource, Renderer/Operation, DerivativeStore, ImageVariant. Resolvers and renderers are registered from config or at runtime, and the route layer (Route::image($prefix) / Image::routes()) is opt-in rather than auto-registered. For a Laravel application this is a clean fit: everything is configuration- and container-driven, nothing requires a service provider fork, and the URL-signing and rendering paths can be swapped independently. The trade-off is that it is no longer a drop-in "resize this file" utility — adopting 2.x is a small platform decision about where image URLs are produced and where derivatives live.

Integration feasibility. Three hard gates exist before any code is written:

  1. Runtime floor. PHP 8.3+ and Laravel 12+ (decision 0001). Any application still on PHP 8.1/8.2 or Laravel 10/11 cannot adopt this at all. This is the single largest scoping input and should be checked against every app in scope on day one.
  2. Alpha dependency chain. Media ids resolve through the media resolver of laravel-mediatheque 2, which has not shipped yet — the release notes say it "ships in its next alpha" and instruct ^2.0@alpha. This means the package cannot be installed and exercised end-to-end on its own today unless you only use the disk resolver. That is a real sequencing constraint, not a footnote.
  3. Rendering engine change. Imagine is gone; rendering is Intervention Image 4 (intervention/image >= 4.3.4) via InterventionRenderer, with an auto driver preferring libvips, then Imagick, then GD. Production image quality/performance therefore depends on what is installed on the host — libvips in particular requires FFI and a system library.

The disk resolver alone (DiskResolver, images on any Laravel disk under an optional root, path containment, version from mtime or S3 ETag) is independently useful and is the lowest-risk way to get hands-on with the alpha.

Technical risk.

  • Alpha maturity. This is 2.0.0-alpha.1. The 1.x code is removed outright, the 1.x API only returns as a compatibility layer in the beta (decision 0007), and only 1.x URLs are decoded today. Anything calling the 1.x PHP API breaks immediately with no shim.
  • Front-end coupling removed. Decision 0008 drops the JavaScript package; every URL must now be built and signed server-side. Any Blade/JS/Alpine/Inertia code that currently constructs image URLs client-side needs rework, and any cached HTML or CDN-edge URL generation done in JS stops working.
  • Operational dependencies are now explicit. Correct behaviour requires a working atomic lock store (image.derivatives.lock), a derivatives disk, a signing key (derived from APP_KEY/APP_PREVIOUS_KEYS), and, for libvips, FFI and a system library. Each of these is a new failure surface.
  • Signature/expiry semantics. Private sources only ever get expiring signed URLs; in strict mode an unsigned spec gets a signed URL and presets are served only at their current version and widths. Getting strict wrong in production is a 403 incident, not a soft failure.
  • Dependency on a sibling alpha. laravel-mediatheque 2 is also pre-release, so you would be pinning two moving packages simultaneously.
  • Bus factor / release process. The release workflow (pre-releases tagged from a green v2.x commit) and the CI matrix (PHP 8.3–8.5 × Laravel 12–13 × GD/Imagick/libvips, Larastan at max level) are strong signals of engineering discipline, but this reads as a small-team or single-maintainer project. Treat upstream responsiveness as a risk to monitor, not a given.

Key questions to put to the maintainers (and to your own platform team).

  • When does laravel-mediatheque 2 alpha land, and is the ^2.0@alpha constraint stable for the duration of our pilot?
  • What is the beta date for the 1.x API compatibility layer, and does it cover the specific 1.x calls we use (not just "the API")?
  • Is there any path to 2.x on PHP 8.2 / Laravel 11, or is decision 0001 final for the entire 2.x line?
  • What is the behaviour when the lock store is unavailable — fail-open (duplicate renders) or fail-closed (503s)?
  • How are signing key rotations handled for URLs already handed to browsers/CDNs (APP_PREVIOUS_KEYS semantics, overlap window)?
  • Does the opt-in image route inherit session middleware in our app, and does image:doctor's session-cookie check flag it as a problem we must fix?
  • What is the upgrade contract for presets versions — can a preset's widths be changed without invalidating cached derivatives?

Integration Approach

Stack fit. A good fit only for applications already, or imminently, on PHP 8.3+ and Laravel 12+. For those, the package is idiomatic: config-driven, container-resolved, no global state, an opt-in route, and a testing story (Image::fake() with an in-memory derivative store, plus published contract test traits for SourceResolver, Renderer, DerivativeStore, ImageVariant). The contract test traits are unusually valuable here — they let us validate our custom resolver or store against the package's own expectations rather than against documentation.

Migration path. Plan it in three stages rather than as a single upgrade:

  1. Inventory (now). Grep for 1.x API usage (Image::make, ->resize, ->url, any Imagine references), JS-side URL construction, and existing derivative directories. The 1.x PHP API has no replacement in alpha 1 — this inventory defines the size of the blocker. Confirm PHP/Laravel versions for every app.
  2. Greenfield / isolated adoption (alpha). Adopt 2.x in one non-critical surface using only the disk resolver and DiskStore, with the route opt-in and strict on. Run php artisan image:doctor in CI as a hard gate — it checks the driver and its formats, FFI/libvips, the disks (--write performs a real write/read/delete), the lock store, the signing key, the route and its session-cookie behaviour, and the URL host. This is the single most valuable operational asset in the release and should be treated as a required pipeline step, not a debugging convenience.
  3. Cut over (beta). Wait for the 1.x compatibility layer before migrating existing call sites; verify existing 1.x URLs still decode through UrlCodec as promised. Then flip presets to their v2 versions and let versioned URLs carry the immutable cache headers.

Compatibility notes. 1.x URLs continue to be decoded — so a mixed fleet (some pages emitting v1 URLs, some emitting v2) will work during rollout. That is the key property that makes a gradual migration possible and should be verified explicitly rather than assumed. Publish config/image.php and change only the keys you need; the config is designed for partial overrides.

Sequencing (dependency-ordered).

  1. Confirm PHP 8.3+/Laravel 12+ on the target app; otherwise stop.
  2. Provision the derivatives disk, the lock store (Redis preferred — atomic lock semantics matter), and confirm APP_KEY/APP_PREVIOUS_KEYS are set and rotated sensibly.
  3. Install with the prerelease constraint; publish config; install intervention/image >= 4.3.4 and choose a driver (libvips where FFI is available and permitted by security review; Imagick as the pragmatic default; GD as fallback).
  4. Wire image:doctor into CI and staging deploy gates.
  5. Build the smallest vertical slice: one preset, one source on a disk, Image::for(...)->preset(...)->url(), route enabled, verified through the CDN.
  6. Only then: front-end teams migrate URL generation server-side (decision 0008 makes this mandatory, not optional).
  7. Only then: bulk-migrate 1.x call sites once the compatibility layer is in beta.

Operational Impact

Maintenance. Alpha churn is the dominant cost. Expect breaking changes between alpha and beta and between beta and GA; pin exact prerelease versions and upgrade deliberately, reading decision records (0001, 0002, 0007, 0008, 0009 are the load-bearing ones) rather than changelogs. The dependency on laravel-mediatheque 2 means two packages must move in step — budget for that as a joint upgrade unit, not two independent ones. The removal of the JS package is a permanent maintenance shift: URL generation is now server-side only, so any future surface (mobile app, SPA, edge worker) needs a server endpoint or a signed-URL API rather than a client library. Long-term, the contract-based design should reduce maintenance — swapping a renderer or store is an implementation change, not a fork.

Support. Documentation is genuinely good for a pre-release: getting started, presets, URLs and signatures, and delivery-behind-a-CDN guides, including a concrete Cloudflare walkthrough. image:doctor converts most "images are broken" tickets into a self-service diagnostic. That said, support load will concentrate in three predictable areas: 403s from signature/expiry/strict-mode mistakes, 503s from render lock contention, and missing-format errors from a driver that lacks AVIF/WebP/HEIC support. Write runbooks for those three before go-live. Note also that Image::fake() and InMemoryDerivativeStore mean test failures won't mask real disk/lock/driver problems — integration coverage must exist separately.

Scaling. The design scales the way image pipelines should: render once per derivative behind an atomic lock, store on a disk, serve with Cache-Control: public, max-age=31536000, immutable for versioned URLs, private for private sources, plus ETag and 304s, and either stream or redirect to the store's URL (public disks). Put a CDN in front and origin load becomes near-zero for warm presets. Watch three cost centres: (a) derivative cardinality — presets × responsive widths × formats multiplies fast, and each one is a stored object to pay for and to invalidate; (b) cold-start stampedes — mitigated by the lock plus 503/Retry-After, but a new preset version is a fleet-wide cold render, so roll preset versions out deliberately; (c) render memory and CPU — the renderer temporarily raises image.memory_limit, and libvips/GD worker sizing should be set from observed p95, not guessed. DiskResolver caches the S3 ETag-derived version for version_ttl seconds, which bounds metadata lookups but is also your staleness window.

Failure modes to instrument explicitly.

  • Lock contention → 503 + Retry-After. Correct behaviour, but it will surface as user-visible latency or errors during cache-miss bursts. Alert on 503 rate, not just on 5xx in aggregate.
  • Lock store unavailable. Unclear from the notes whether this degrades to duplicate renders or to hard failures — resolve this with the maintainer before launch, since it determines blast radius.
  • Signing key mismatch / rotation. Expired or wrongly-signed URLs return 403 with no hint. Ensure APP_PREVIOUS_KEYS overlap covers the longest TTL in use plus CDN cache lifetime.
  • Disk write failures on the derivatives disk — image:doctor --write catches configuration errors at deploy time; runtime failures still need a metric.
  • Route leaking session cookies, flagged by image:doctor. The image route should be stateless and cache-safe; if it inherits session middleware, CDN caching semantics break.
  • Source disappearance / non-containment. Version derived from mtime or ETag means a changed source silently produces a new URL and a fresh render — fine, but it means stale derivatives are never automatically reclaimed. Plan a pruning job.
  • Metadata edge cases — EXIF orientation, embedded colour profiles, HEIC sources — are handled by the renderer, but only on drivers that support them. GD lacking a format is a silent quality regression, not an error.

Ramp-up. Assume one to two engineer-days to a working vertical slice for someone fluent in Laravel and Image 4, and materially more for the full migration, because the 1.x API gap blocks existing call sites until beta. Ramp-up aids are strong and should be used in order: the four guides, then image:doctor as an interactive teacher on a staging box, then the public contract test traits as executable documentation of what each extension point must do. The conceptual jumps to plan for are (a) URLs as the primary unit of work rather than images — you build a spec, sign it, hand out a URL; (b) versioning as the cache-invalidation primitive; (c) strict mode as a security posture that will initially feel like it is fighting you. Do not attempt a big-bang migration ahead of the compatibility layer; a phased, one-surface-at-a-time rollout with image:doctor as the gate is the only sequencing that matches the release's actual maturity.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console