outl1ne/nova-media-hub
A media library and file manager for Laravel Nova. Upload, organize, search, and attach images and files to your resources through a clean, centralized interface, keeping all your assets in one place and simplifying media handling across the admin panel.
Architecture fit
laravel/nova (commercial, per-site license) is a hard prerequisite. If we are not already on Nova, the evaluation ends here — we should not adopt Nova as a side effect of wanting a media library.spatie/laravel-medialibrary, so it does not introduce a wholly foreign persistence model; it adds an admin surface (browse, folders, search, upload, crop) plus a Nova field for attaching existing media to any resource. That is genuinely the expensive part to hand-roll — realistically one to three sprints of undifferentiated internal tooling.Integration feasibility
composer require, publish provider config, migrate, storage:link if public disk, register the tool in NovaServiceProvider::tools(), add the field to a resource.composer.json require block and confirm the Nova major, PHP floor, and Laravel range. If our Nova major is not listed, we are evaluating a fork, not a dependency.dist/ assets. If not, CI needs a deliberate build step inside vendor/, which is fragile and will not survive composer install.Technical risk
| Risk | Severity | Note |
|---|---|---|
| Thin community validation (46 stars, 0 dependents) | High | We are an early adopter; assume we may need to patch a fork |
| Single-maintainer release cadence tied to Nova majors | High | Compat lands on the maintainer's schedule, not ours |
| Anomalous last-release date (2026-07-29) | Medium | Data-quality flag — verify changelog/commit activity on the repo directly before treating "maintained" as fact |
| Second media owner if Spatie/bespoke uploads already exist | High | Creates exactly the ambiguity we are trying to remove |
| Conversion infra (GD/ImageMagick, memory, queue vs sync) | Medium | Silent failures on queue workers; sync crops stall the Nova UI |
| Referential integrity on delete | Medium | Package will not guard "is this in use?" for us |
| Private-disk signed/expiring URLs | Medium | Do not discover in production with cached HTML |
Key questions for the team
Stack fit
Migration path
media/2024/06/foo.jpg into our columns welds us to the package's path convention and turns rollback into a file migration.media:import-legacy), run in staging with record-count and URL-resolution assertions, then production. Keep legacy upload fields read-only for at least one release cycle as a fallback.Compatibility
MediaService / trait (attachMedia(), heroUrl(), mediaInUse()). One hour of work converts a future fork-and-own decision from a refactor into a swap.thumb, card, hero, og) in config, referenced via constants or an enum. A per-feature free-for-all is expensive to unwind later.Sequencing
composer.json. No code.config/nova-media-hub.php (disk, path prefix, accepted types, max size, conversions), wrapper layer, conversion vocabulary, Storage::fake() feature test asserting URL resolution through our accessor.config:clear/optimize:clear runbook step.Maintenance
Support
src/, the published config, and the migrations as sources of truth.Scaling
Failure modes to pre-write into the runbook
client_max_body_size, upload_max_filesize, post_max_size, or a Livewire limit, not the package. Check network tab, then PHP config on every environment including workers.config:clear / optimize:clear is the first diagnostic.dist/ is not in the tag, composer install in CI produces a broken Nova UI.Ramp-up
How can I help you explore Laravel packages today?