Open source
Media Library for Laravel
composer require roundly-consulting/media-library-for-laravelOverview
A native media library for Laravel. Attach files to your Eloquent models in named buckets, or store global media with no owner — all in one polymorphic media table, stored through Laravel's own filesystem on any disk you configure. It handles everything after the upload: image variants, responsive srcset, blur-up placeholders, private streaming, deduplication and CDN URLs. Built with only official Laravel and Symfony dependencies — no third-party media or image vendors.
What you get
Buckets & global media
Attach files to named buckets on any model, or store ownerless global media — all in one polymorphic table.
Multi-disk storage
Any Laravel disk, with separate disks for originals and variants — keep originals cold, variants hot.
Image variants
Native image-only derivatives via ext-imagick with a GD fallback. Sync by default, queue opt-in.
Responsive & LQIP
ThumbHash + Blurhash blur-up placeholders and ready-made responsive srcset helpers.
Private URLs & streaming
One temporaryUrl() API that presigns natively or falls back to a signed streaming route.
Dedup & CDN-ready
Content-addressable storage with refcount-guarded deletes, plus a pluggable CDN URL generator.
Facade, DI or actions
One MediaLibrary facade, an injectable manager or single-purpose actions — plus a recording fake that touches no disk.
Documentation
Installation
Install via Composer, publish the migration, and optionally publish the config and the streaming route file.
Configuration
Every config key and its default — disks, image driver, dedup, placeholders, responsive and CDN.
Buckets
Declare named media buckets on a model — disks, mime allowlist, visibility, fallbacks and variants.
The MediaLibrary facade
Tour the MediaLibrary facade — global adds, the for($model) handle, move/copy/replace/delete, drafts, attach, variants and rules.
DI and actions
Skip the facade: inject MediaLibraryManager or call a single-purpose action — the facade method → action map.
Adding media
Add files from uploads, requests, URLs, disks, strings, base64 or streams through MediaLibrary::for() and the PendingFileAdd builder.
Upload safety
Every name and type that reaches storage is untrusted — mime sniffing, safe file names, honest extensions and guarded remote fetches.
Reading media
Read an owner's media through MediaLibrary::for() — collections, first media, URLs and temporary URLs — plus attributes.
Global media
Store ownerless, app-wide assets — logos, shared PDFs — through the MediaLibrary facade.
Image variants
Declare resized/reformatted derivatives that generate automatically; control sizing, format, quality and disk.
Responsive images
Generate a width ladder and get ready-made srcset and a full <img> tag with an LQIP background.
Placeholders (LQIP)
ThumbHash and Blurhash blur-up placeholders, plus recorded pixel dimensions, computed on add.
URLs, streaming & downloads
Public URLs, presigned temporary URLs for private media, and an efficient range-aware streaming route.
Deduplication & integrity
Content-addressable storage with refcount-guarded deletes and an optional read-time checksum check.
Artisan commands
Regenerate variants, clean orphaned files, clear buckets, verify checksums and prune expired drafts.
Testing
Swap in MediaLibrary::fake() to record adds, moves and deletes without touching a disk — or test end-to-end against Storage::fake().
Requirements
PHP 8.4+, Laravel 12 or 13, ext-fileinfo, and ext-imagick or ext-gd for variants.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.