spatie/laravel-medialibrary
67.8
Adequate · 19 September 2026
5.8k
lines of production code
PHP
primary language
1
measurement over time
What this system is
This system is a Laravel package for managing media assets, enabling developers to attach files to Eloquent models and automatically generate responsive images and conversions. It provides a configurable infrastructure for storing media on various disks, handling background processing via queues, and managing the full lifecycle of media files including cleanup and regeneration. The library supports modern web standards through responsive image rendering and offers extensible hooks for custom file naming, path generation, and URL handling.
How it got here
2015–2017 — v10 architecture and responsive images
16 changes.
This period focused on the foundational restructuring for version 10, introducing the HasMedia interface and InteractsWithMedia trait to redefine media handling. Significant work was dedicated to implementing a robust responsive image system, featuring file-size-optimized width calculators, configurable quality settings, and inline rendering logic. The release was supported by extensive test coverage, including architectural contracts, S3 integration, and performance validation, alongside major dependency upgrades to PHP 8.2 and Laravel 10-13.
2020 — Media library architecture overhaul
31 changes.
This period focused on a comprehensive architectural redesign of the Media Library package, introducing extensible interfaces for URL generation, path handling, and file naming to replace rigid internal logic. It established a robust, queueable conversion system with deferred execution and added a configurable command-line interface for media regeneration and cleanup. The work also expanded format support to include AVIF and WebP while implementing a structured exception hierarchy and comprehensive test coverage for the new components.
2022–2026 — Extensibility and observability features
8 changes.
This period focused on enhancing the library's extensibility and observability by introducing pluggable file removal strategies and domain-specific events for granular lifecycle tracking. It also added structural improvements such as a CollectionPosition enum for media ordering and AI development resources, supported by comprehensive test coverage for new components.
Features
Added AI skill for Laravel Media Library development
The resources/boost area now includes a new 'medialibrary-development' skill that provides AI code assistants with guidelines and reference documentation for the spatie/laravel-medialibrary package. This addition enables the AI to assist with tasks such as associating files with Eloquent models, defining media collections and conversions, generating responsive images, and managing media uploads and retrieval.
resources/boost · high confidence
Added CollectionPosition enum for media ordering
A new CollectionPosition enum has been introduced to define specific ordering positions for media items within a collection. This enum supports 'first' and 'last' positions, enabling users to explicitly control where new media assets are placed relative to existing ones in a collection.
src/Enums · high confidence
Added media table migration stub with UUID and responsive image support
A new database migration stub for the 'media' table has been introduced, defining the schema for storing media assets. This schema includes a unique UUID column, support for polymorphic relationships via 'model' morphs, and specific fields for file metadata such as MIME type, disk location, and size. Notably, the table structure now supports responsive images through a dedicated JSON column and includes an indexed order column for sorting, alongside JSON columns for manipulations, custom properties, and generated conversions.
database · high confidence
Initial configuration file for Media Library package
The package now ships with a \config/media-library.php\ file, allowing users to customize storage disks (including a separate disk for conversions), file size limits, queue settings for image processing, and security constraints like disallowed extensions. This change introduces the package's configuration schema for the first time, enabling direct tuning of media handling behavior without modifying core code.
config · high confidence
Introduce configurable file remover architecture
The library now supports a pluggable file removal strategy via a new \FileRemover\ interface, \DefaultFileRemover\ implementation, and a \FileRemoverFactory\. Users can configure a custom file remover class via the \media-library.file\_remover\_class\ config option, allowing them to override how media files, conversions, and responsive images are deleted from storage. The default behavior remains unchanged, but the new structure enables custom deletion logic (e.g., honoring custom file namers or handling specific disk configurations) without modifying core library code.
src/Support/FileRemover · high confidence
Introduce extensible URL generator architecture with custom path support
The library now uses a new, extensible URL generation system located in \src/Support/UrlGenerator\. This introduces a \UrlGenerator\ interface and a \BaseUrlGenerator\ abstract class that handle URL construction, including proper URL encoding for local disk paths and versioned URLs. A \DefaultUrlGenerator\ implements this interface for standard use cases, while the \UrlGeneratorFactory\ allows users to configure a custom URL generator class via the \media-library.url\_generator\ config option. Additionally, the system supports setting a custom \PathGenerator\ per media model, enabling customized file path structures for URL generation.
src/Support/UrlGenerator · high confidence
Introduce file-size-optimized responsive image width calculation
Added a new \FileSizeOptimizedWidthCalculator\ that generates responsive image widths by iteratively reducing the predicted file size (scaling down by 30% per step) until it reaches a minimum threshold of 10 KB or the width drops below 20 pixels. This calculator uses the original image's pixel density and aspect ratio to estimate file sizes for smaller variants, providing a more storage-efficient set of responsive images compared to fixed-step calculations.
src/ResponsiveImages/WidthCalculator · high confidence
Introduction of HasMedia interface and InteractsWithMedia trait for v10
This change introduces the \HasMedia\ interface and the \InteractsWithMedia\ trait, which serve as the core contract and implementation for media handling in the new v10 architecture. The \HasMedia\ interface defines the public API for attaching, retrieving, and managing media collections, while the \InteractsWithMedia\ trait provides the concrete logic for these operations, including support for temporary uploads and integration with Laravel's service provider. This structural shift establishes the foundation for the updated media library functionality.
src · high confidence
Introduction of PerformConversionsJob for queued media conversion tasks
A new PerformConversionsJob class has been added to handle media conversion operations asynchronously via Laravel's queue system. This job accepts a ConversionCollection, a Media model, and an optional flag to process only missing files, delegating the actual conversion work to the FileManipulator. This enables non-blocking, background processing of media conversions, improving application responsiveness during heavy media handling.
src/Conversions/Jobs · high confidence
Introduction of domain-specific event classes for media operations
The library now exposes specific event classes to allow applications to react to key moments in the media lifecycle. New events include \ConversionWillStartEvent\ and \ConversionHasBeenCompletedEvent\ for conversion processes, \CollectionHasBeenClearedEvent\ and \MediaHasBeenAddedEvent\ for media collection management, and \ResponsiveImagesGeneratedEvent\ for responsive image generation. These events provide structured data (such as the affected Media model, Conversion object, or collection name) to listeners, enabling more granular handling of media-related actions.
src/Conversions/Events, src/MediaCollections/Events, src/ResponsiveImages/Events · high confidence
Media model lifecycle observers added
A new MediaObserver class has been introduced to handle media model lifecycle events. When a media item is created, it automatically assigns the highest order number if sorting is enabled. During updates, the observer synchronizes the media file path and file names based on configuration settings, and triggers the regeneration of derived files (conversions) if manipulations have changed. Upon deletion, it ensures all associated files are removed from storage, with support for soft-delete scenarios.
src/MediaCollections/Models/Observers · high confidence
New downloader architecture with SSL and HTTP client options
The library now introduces a new \Downloader\ interface and two implementations: \DefaultDownloader\, which uses PHP's native stream context to download files with configurable SSL verification and a custom User-Agent, and \HttpFacadeDownloader\, which leverages the Laravel HTTP client for downloads with similar User-Agent support and error handling. This allows users to choose between native PHP streams and the Laravel HTTP facade for media downloads.
src/Downloaders · high confidence
New media cleanup and clearing commands
Two new Artisan commands are introduced to manage media storage: \media-library:clean\ removes deprecated conversion files, orphaned responsive images, and optionally deletes orphaned media items and directories, while \media-library:clear\ deletes all media items within a specified model type and collection. Both commands support dry-run modes, rate limiting, and progress indicators to safely manage large-scale cleanup operations.
src/MediaCollections/Commands · high confidence
New media collection and file handling components
The \src/MediaCollections\ area now includes several new classes that define the core behavior for managing media. \File\ provides a simple value object for file metadata. \FileAdder\ and \FileAdderFactory\ handle the logic for adding files (local, remote, or from requests) to media collections, including setting file names, sizes, and orders. \Filesystem\ manages the actual storage operations, copying files to the appropriate disk and handling remote file streaming. \HtmlableMedia\ allows media items to be rendered as HTML strings, supporting conversions and responsive images. \MediaCollection\ serves as a configuration object for defining collection properties like disk names, accepted MIME types, and size limits. \MediaRepository\ provides a centralized interface for querying media records, including retrieving collections, filtering by model type, and identifying orphaned media.
src/MediaCollections · high confidence
New media model concerns for UUIDs, sorting, and custom properties
Added three new Eloquent model concerns to the media library: \HasUuid\ automatically generates a UUID for new media records and provides a \findByUuid\ lookup method; \IsSorted\ enables ordered management of media items with methods to set, retrieve, and reorder items by their position; and \CustomMediaProperties\ allows storing and retrieving custom headers as metadata on media records.
src/MediaCollections/Models/Concerns · high confidence
New media regeneration command with batch and queue options
A new \media-library:regenerate\ artisan command has been added to allow users to regenerate derived images for media items. This command supports filtering by specific model types, individual IDs, or a starting ID range (with an option to exclude the starting ID). It includes flags to regenerate only missing conversions, include responsive images, and force execution in production. Additionally, it introduces a \--queue-all\ option to send conversions to the queue even if they are normally processed synchronously, and automatically disables the maximum execution time limit when the queue connection is set to 'sync' to prevent timeouts during large batches.
src/Conversions/Commands · high confidence
Behavioural changes
Custom serialization for media collections with preview and original URLs
The MediaCollection class now implements Htmlable and custom JSON serialization to expose detailed media metadata, including preview\_url and original\_url, when converted to HTML or JSON. This behavior is controlled by the new 'media-library.use\_default\_collection\_serialization' configuration option; when disabled (the default), collections serialize into a structured array keyed by UUID containing file details, rather than using the parent Eloquent collection's default serialization. This ensures that frontend components receive consistent, rich media data including preview and original file URLs.
src/MediaCollections/Models/Collections · high confidence
Customizable path generation for media storage
Users can now define custom path generators for specific Eloquent models or globally via configuration. The library introduces a \PathGenerator\ interface and a \DefaultPathGenerator\ implementation that respects a new \media-library.prefix\ config option to prepend a custom directory to stored media paths. A \PathGeneratorFactory\ handles the resolution logic, allowing developers to register custom generators per model (including support for morphed map relations) to control how media files are organized in storage.
src/Support/PathGenerator · high confidence
Introduce extensible FileNamer abstraction for media file naming
The library now uses an abstract \FileNamer\ class with a \DefaultFileNamer\ implementation to handle the generation of original, conversion, responsive, and temporary file names. This change replaces previous logic (likely regex-based) with explicit path manipulation, allowing users to customize how media files are named by extending the \FileNamer\ class. The default behavior strips extensions for responsive names and appends the conversion name for derived images.
src/Support/FileNamer · high confidence
Introduces configurable tiny placeholder generation with a blurred implementation
The library now supports generating tiny image placeholders through a new \TinyPlaceholderGenerator\ interface, allowing for configurable placeholder strategies. A default \Blurred\ implementation is provided, which creates a 32x32 pixel blurred JPEG from the source image using the \ImageFactory\. This change enables users to customize how tiny placeholders are generated rather than relying on a hardcoded internal method.
src/ResponsiveImages/TinyPlaceholderGenerator · high confidence
Introduction of responsive image rendering with inline size calculation
The view layer now includes new Blade templates for rendering responsive images (\responsiveImage\, \responsiveImageWithPlaceholder\) and a placeholder SVG generator. The \responsiveImageWithPlaceholder\ template specifically implements an inline JavaScript snippet that dynamically calculates the container width to set the \sizes\ attribute, addressing previous issues where width remained fixed at 1px. These views also ensure that the \alt\ attribute is consistently applied to image tags for accessibility.
resources/views · high confidence
Media model now supports null expiration for temporary URLs
The \getTemporaryUrl\ method on the Media model now accepts a \null\ expiration value. When \null\ is passed, the method falls back to the \media-library.temporary\_url\_default\_lifetime\ configuration setting, allowing users to rely on the global default rather than providing an explicit expiration time for every call.
src/MediaCollections/Models · high confidence
New conversion execution model with deferred and queued options
The \src/Conversions\ components have been rewritten to support a new execution strategy for media conversions. The \Conversion\ class now exposes \queued()\, \nonQueued()\, and \deferred()\ methods, allowing users to control whether conversions run synchronously, on a background queue, or deferred until the end of the current request (Laravel 11.23+). The \FileManipulator\ orchestrates this by partitioning conversions into these three categories and executing them accordingly, while \ConversionCollection\ handles loading conversions from models and applying database-stored manipulations.
src/Conversions · high confidence
New support utilities and refined ZIP streaming behavior
This update introduces several new support classes: File (providing human-readable size formatting and MIME type detection via Symfony MimeTypes), ImageFactory (loading images via the configured driver), MediaLibraryPro (checking for Pro installation), RemoteFile (wrapping remote storage keys), and TemporaryDirectory (creating isolated temp folders). It also refactors MediaStream to allow passing options to ZipStream, strip path-traversal segments from zip\_filename\_prefix, and optimize filename suffix generation to avoid unnecessary renaming.
src/Support · high confidence
Refactored image generators to support AVIF, WebP, and configurable FFMpeg settings
The image generation system has been refactored to use a new factory pattern and abstract base class, allowing for more flexible configuration and support for additional formats. AVIF and WebP images are now supported via dedicated generators that convert them to PNG thumbnails. The Video generator now respects configurable FFMpeg timeout and thread settings from the application config, and correctly handles the m4v format. The Image generator dynamically includes TIFF and HEIC/HEIF support when the Imagick driver is enabled. The PDF generator has been updated to support spatie/pdf-to-image v3, allowing for page number selection during conversion.
src/Conversions/ImageGenerators · high confidence
Responsive image generation now supports per-conversion width calculators and quality settings
The responsive image system has been refactored to allow different width calculators to be specified per conversion, enabling more granular control over how responsive variants are sized for specific conversions. Additionally, the generator now respects the quality setting defined on each conversion rather than using a single global default, ensuring that output images match the intended quality for each specific use case. This change also introduces new exception classes for validating tiny placeholder images and refactors the internal registration and deletion logic for responsive images to be more robust.
src/ResponsiveImages · high confidence
Structured exception hierarchy for media collection errors
The library now introduces a dedicated exception hierarchy under \Spatie\\MediaLibrary\\MediaCollections\\Exceptions\ to provide clearer error reporting. A new abstract \FileCannotBeAdded\ base class serves as the foundation for specific exceptions such as \DiskCannotBeAccessed\, \FileNameNotAllowed\, \FileIsTooBig\, and \MimeTypeNotAllowed\. This change ensures that users can catch specific failure modes—like security-related filename sanitization or disk access issues—rather than relying on generic exceptions.
src/MediaCollections/Exceptions · high confidence
Fixes
Introduce dedicated action classes for conversion execution and manipulation
The conversion pipeline in \src/Conversions/Actions\ has been refactored to use specific action classes. \PerformConversionAction\ now orchestrates the entire conversion lifecycle, including image generation, manipulation, responsive image creation, and file storage. \PerformManipulationsAction\ handles the actual image processing, introducing a fix for the \keepOriginalImageFormat\ logic by correctly checking the media extension against a list of supported formats (jpg, jpeg, pjpg, png, gif, webp) using a case-insensitive comparison. This change also ensures that temporary files are generated with random names to avoid collisions and properly handles unsupported image formats during manipulation.
src/Conversions/Actions · high confidence
Test coverage
Added S3 integration tests; Added architectural and interface contract tests; Added comprehensive test coverage for media conversion behaviors; Added feature tests for media management operations; Added performance tests for media lazy loading behavior; Added test fixture files for image processing tests; Added test helper for custom path generator scenarios; Added test support classes for custom media library implementations; Added test support classes for mail attachment scenarios; Added test support for fixed-width responsive image calculation; Added test support models for media library features; Added test support views for mailable and media testing; Added tests for BaseUrlGenerator behavior; Added tests for FileAdder conversions disk configuration and multi-disk storage; Added tests for HttpFacadeDownloader; Added tests for custom path generator configuration and validation; Added tests for file size formatting and media stream zip generation; Added tests for image generator conversions and configuration; Added tests for media collection events, filename sanitization, and media movement behavior; Added tests for media conversion, deletion, and collection behaviors; Added tests for media library CLI commands; Added tests for remote header handling and custom path generation; Added tests for responsive image generation and optimization; Expanded test coverage for media library core operations; Snapshot test added for responsive image rendering with placeholder.
Dependencies
Major dependency upgrade and PHP 8.2+ requirement
The package has been updated to require PHP 8.2 or higher and now supports Laravel 10, 11, 12, and 13. Key dependencies have been upgraded, including spatie/image to v3.3.2, maennchen/zipstream-php to v3.1, and symfony/console to support versions 6.4, 7, and 8. The composer.json also introduces new required extensions (exif, fileinfo, json) and adds dev dependencies for testing and static analysis, such as Pest, Larastan, and Mockery.
(dependencies) · high confidence
Housekeeping
Repository maintenance and documentation overhaul
This update refreshes the project's development infrastructure and documentation. It introduces an \.editorconfig\ for consistent coding styles, configures PHPStan for static analysis, and updates the PHPUnit configuration. The legacy Travis CI and Scrutinizer CI configurations have been removed in favor of modern GitHub Actions. Documentation has been significantly expanded with a new \UPGRADING.md\ guide covering migrations from v7 through v11, and the \README.md\ has been rewritten to include comprehensive usage examples, testing instructions, and support information.
(repo-wide) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 68.
Lenses
- Code Health 93
- Architecture 97
- Maturity 59
- Readiness 80
- Security 65
Changes since last survey
- 300 commits — 230 feature/other, 70 fixes
By area
- (root) — 100 commits
- src/MediaCollections — 40 commits
- src/Conversions — 29 commits
- (repo) — 22 commits
- src/Support — 15 commits
- .github/workflows — 14 commits
- docs/handling-uploads-with-media-library-pro — 10 commits
- src/InteractsWithMedia.php — 10 commits
- config/media-library.php — 9 commits
- tests/Feature — 8 commits
- docs/advanced-usage — 7 commits
- docs/basic-usage — 4 commits
- docs/converting-images — 4 commits
- tests/Conversions — 4 commits
- docs/installation-setup.md — 3 commits
- src/Enums — 3 commits
- src/HasMedia.php — 3 commits
- .github/ISSUE_TEMPLATE — 2 commits
- src/Downloaders — 2 commits
- tests/Support — 2 commits
Notable commits
- fix: Fix #3889: Clean orphaned responsive images for base image when withResponsiveImages is removed (#3913)
- fix: Fix DivisionByZeroError in File::getHumanReadable() (#3549)
- fix: Fix PHPDoc property name to use snake_case (#3895)
- fix: Fix S3 conversions inheriting original media's ContentType (#3914)
- fix: Fix SVG files loosing transparency during conversion (#3728)
- fix: Fix adding orientation as a manipulation.
- fix: Fix all PHPStan errors
- fix: Fix an issue where the same mediaCollections could be registered multiple times. (#3598)
- fix: Fix awkward phrasing: 'want to not move, but copy' -> clearer wording
- fix: Fix confusing documentation for Media::setNewOrder method (#3759)
- fix: Fix deletion of files without extension (#3664)
- fix: Fix docs bugs: 'to the where' typo and 'how to working with conversion' grammar
- fix: Fix double URL encoding for getTemporaryUrl() with non-ASCII filenames on local disk (#3950)
- fix: Fix flaky S3 temporary-URL tests by comparing without timing params (#3940)
- fix: Fix getStream path concatenation for custom PathGenerator
- fix: Fix getStream path concatenation for custom PathGenerator
- fix: Fix handling of dots in conversion names for clean command (#3551)
- fix: Fix imagedestroy deprecation (#3893)
- fix: Fix issue when using moves_media_on_update with S3 does not move the entire directory (#3647)
- fix: Fix manipulations not applying to non default collections (#3589)
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
spatie/laravel-medialibrary was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 3bbac92f7c6ad4a162307c59378d5125a5ca8868 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.