classic-o/nova-media-library
A Laravel Nova media library package for browsing, uploading, organizing, and selecting media files in a clean Nova interface. Manage assets and attach them to resources without leaving the admin panel.
Build vs. buy for admin-side media management. This package is a thin Nova UI layer over spatie/laravel-medialibrary: a drag-and-drop upload tool, a browsable asset library, and a field that attaches media to any Nova resource. On an existing Nova stack, "buy" is one Composer dependency plus a few hours of configuration. "Build" is one to three sprints of custom Vue/Nova work for an equivalent upload-browse-attach screen, plus everything you'd still have to build underneath it (storage abstraction, conversions, thumbnails, deletion semantics). The honest trade-off is not license cost — MIT, zero dollars — it's the carrying cost of a 152-star, low-activity package that will need attention at the next Nova major.
Content model: shared asset library vs. per-record uploads. The distinguishing capability over a plain Nova File field is a persistent library that outlives any single record. An editor uploads a hero banner or a brand logo once and references it from many posts, product pages, and help articles. That is a product decision that has to be made before content accumulates: retrofitting a shared library onto thousands of per-record uploads is a data migration, not a settings change. Decide now, because the alternative (per-record files) produces a bucket full of near-duplicate images and no way to swap a logo site-wide.
Roadmap unblocking for content-heavy releases. Any backlog item where editors attach images or documents to entries — blog posts, product galleries, help-center articles, landing pages, case studies — moves from "blocked on bespoke media subsystem" to "schedulable this sprint." This is a schedule-risk reduction play, not a platform investment. Frame it that way in planning: the value is the release date you protect, not the feature you build.
Editorial self-service and marketing velocity. Today, every image change is likely an engineering ticket: someone edits a path, redeploys, or manually pushes to a bucket. With this in the admin panel, editors upload, preview, attach, replace, download, and delete without a deploy. That converts a recurring interrupt stream into a one-time integration cost. If your team fields more than a couple of "can you swap the homepage banner" requests a month, the payback period is short and easy to defend.
Alt text, captions, and credits become an editorial responsibility instead of an engineering afterthought. Medialibrary's custom properties let editors record alt text and credits in the same place they upload the file. That's the cheapest possible moment to fix accessibility debt — at the point of upload, by the person who knows what the image is — rather than during an audit months later.
A narrow, honest data contract for the public API. Storing a media ID and resolving the URL at render time behind a single accessor means swapping local disk for S3/CDN, changing path conventions, or later migrating to a real DAM becomes one method edit plus a data migration rather than a rewrite of every Blade template, email, and sitemap. This is a product decision about how much future infrastructure change is allowed to cost you.
Sizing the risk properly. The blast radius is one model, one field, one tool. If the package turns out to be incompatible with your Nova major, a fork or an in-house replacement is days of work, not weeks. That asymmetry — small downside, meaningfully deferred roadmap — is what makes this a reasonable bet rather than a gamble.
Adopt when all of these are true:
spatie/laravel-medialibrary. This package is the UI, not the storage engine. It brings Medialibrary's migrations, config, conversions model, and media table along with it. If you're not prepared to own that, you're evaluating the wrong layer.media rows and the files on disk will accumulate without a scheduled sweep. This is a small piece of work, but it is work, and it's the operational hole the package leaves open.Look elsewhere when:
File::make() is the better tool; the shared-library model just adds orphan risk with no reuse benefit.assets/files table and no appetite for two sources of truth. This package brings its own Media model. If you can't commit on day one to which one wins — and treat media as an adapter so consolidation later is a data migration — you'll be reconciling duplicates forever.For executives — the one-paragraph version: Our admin panel can't manage images or documents today, so every asset change routes through engineering. This is a free, open-source add-on for the Laravel Nova admin we already own; it adds drag-and-drop uploads, a reusable asset library, thumbnails, and file replacement in the admin UI. Integration is a Composer dependency and configuration — hours to days, not sprints — against one to three sprints to build the equivalent ourselves. The risk is a small, single-purpose package with modest maintenance activity; the worst case is that a future Nova upgrade requires a fork or a few days of in-house replacement work, which is a bounded cost. Recommendation: adopt on one content-heavy resource, prove it end to end, then roll out.
For engineering — what you're actually signing up for:
spatie/laravel-medialibrary. Not a storage engine. Publish Medialibrary's own config and migrations; the media table becomes part of your schema.composer.json. No floating constraints — a Nova minor bump plus a floating constraint is how you get a blank modal in production on a Tuesday.NovaServiceProvider::tools() and attach the field to exactly one resource first. Then run the full loop by hand in the browser: upload through the tool → attach through the field → save → render on the front end → delete → inspect the media table. That single pass surfaces nearly every integration problem.queue_conversions_by_default in config and run a worker, or a 12 MB upload will time out the modal mid-spinner. Confirm the image driver (GD/Imagick) exists in the container.php artisan storage:link on local; bucket policy and CORS on S3.For the product team — what changes for editors: Editors get a real workflow instead of a ticket queue: search the library before uploading, upload once and attach to many entries, set alt text and captions at upload time, replace a file without touching code. Set the expectation explicitly that browse-first is the habit — the value of the library comes from reuse, and reuse only happens if people look before they upload.
The honest caveat to state out loud, once: This is a small, forkable bet that pays off if someone is watching for the next Nova major. It is not a platform commitment and it is not a DAM. The moment the ask becomes approval workflows, asset versioning, or rights and expiry, we stop extending this and start evaluating real digital asset management.
How can I help you explore Laravel packages today?