# spatie/laravel-medialibrary: attaching files to Eloquent models

> A PHP package that gives Eloquent models a media collection API on top of Laravel's filesystem. It fits Laravel apps that need uploads, conversions and multiple storage disks, and it is a poor fit for anything outside Laravel.

**spatie/laravel-medialibrary** — Associate files with Eloquent models

- Repository: https://github.com/spatie/laravel-medialibrary
- Website: https://spatie.be/docs/laravel-medialibrary
- Stars: 6,163 · Forks: 1,093
- Language: PHP
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/spatie-laravel-medialibrary

## The problem: files that have no home in your schema

A Laravel app usually starts by storing an upload path in a string column. That works until the same record needs a thumbnail, an original, a PDF preview and a downloadable archive, spread across a local disk and S3. Then you are writing your own table, your own path convention and your own cleanup logic.

spatie/laravel-medialibrary targets that gap. The README states the package "can associate all sorts of files with Eloquent models", and it provides what it calls a simple API to work with. The intended user is a Laravel developer who already has models and wants files to be first-class rows rather than columns.

The package is not a general file manager and not a CDN. It is a persistence layer for media attached to records, and the README points to the full documentation at spatie.be/docs/laravel-medialibrary for everything beyond the short examples.

## How media collections sit between your model and the filesystem

The core abstraction is the media collection. A collection is a named slot on a model, and a file added to that slot becomes a media record. The README's first example takes a path and pushes it into the images collection of a News model.

The second example shows the upload path, where the file comes straight from the request instead of the filesystem. The third shows that the same collection name can be written to different disks: downloads goes to local for a small file and to s3 for a big one. Storage is delegated to Laravel's Filesystem, so any disk Laravel supports is available, and the README adds that the package can create image manipulations on images and PDFs that have been added.

That last point is the part worth pausing on. Conversions are not free: they are derived files generated from the original, and the README does not describe in the excerpt how or when that work is scheduled. The repository layout includes a config/ directory and a database/ directory, which is consistent with a published config file and a migration, but the README itself does not walk through either.

## Installing spatie/laravel-medialibrary and adding a first file

The README does not print an install command. It links to the documentation site for setup, and the related searches around this package are dominated by the Composer line, so the package name is the reliable part: spatie/laravel-medialibrary.

After that, the documented path is the package documentation rather than the README. The repository ships a config/ directory and a database/ directory, and the README links to UPGRADING.md for version changes, which is the file to read before moving between major versions.

Once the package is in place, the usage shown in the README is a single chain. This adds a file already on disk to the images collection of a news item:

```php
$newsItem = News::find(1);
$newsItem->addMedia($pathToFile)->toMediaCollection('images');
```

For a real upload the same chain takes the uploaded file object directly, so no intermediate copy is needed:

```php
$newsItem->addMedia($request->file('image'))->toMediaCollection('images');
```

The second argument to toMediaCollection is the disk name, and the README uses it to send a large file to s3 while a small one stays on local:

```php
$newsItem->addMedia($smallFile)->toMediaCollection('downloads', 'local');
$newsItem->addMedia($bigFile)->toMediaCollection('downloads', 's3');
```

What you should see is a media record associated with the model and the underlying file written to the disk you named. The README does not show the retrieval side or the conversion definitions, so treat the documentation site as required reading before you model your own collections.

## Where the package stops being the right tool

The obvious boundary is the framework. Everything here hangs off Eloquent models and Laravel's Filesystem, so a Symfony, Slim or plain PHP application gets nothing from it. The README's own alternatives list points at other PHP packages, not at framework-agnostic storage layers.

The second boundary is operational. Conversions on images and PDFs are extra work performed on files you have added, and the README excerpt does not explain how that work is dispatched, retried or cleaned up when it fails. If your application uploads large video or PDF files on the request thread, that is a design decision you have to make yourself, and the README gives no guidance on it.

The third is scope. If all you need is to push bytes to S3 and hand back a URL, this package adds a media table, a config file and a set of conventions you will not use. Plain Laravel filesystem calls are smaller and have fewer moving parts.

Finally, the README does not document rollback or deletion behaviour for media records, and it does not describe what happens to derived files when the original is removed. That silence matters if you are storing user uploads under a retention policy.

## Alternatives named by the project, and what changes if you pick one

The README lists three alternatives directly: laravel-mediable, laravel-stapler and media-manager. That is unusually honest for a README, and it is the best starting point for comparison because the maintainers chose to name them.

The difference is in the abstraction. This package centres on named media collections attached to a model, with the disk chosen per collection and conversions generated from added files. The alternatives are separate projects with their own attachment models and their own conventions; the README does not describe how they differ in detail, so the comparison has to be made by reading each one.

What you can say from this repository alone is that medialibrary is the one Spatie maintains, that it has a documentation site at spatie.be/docs/laravel-medialibrary, and that its upgrade path is tracked in UPGRADING.md with changes in CHANGELOG.md. If you are choosing between them, those three artefacts are the concrete things to compare, not the feature lists.

## Maintenance, upgrades and the MIT licence

The repository is not archived, and the last push was on 2026-09-14. Releases 11.23.6, 11.23.7 and 11.23.8 landed on 2026-09-01, 2026-09-03 and 2026-09-14 respectively, so the 11.23.x line is being patched at a steady rhythm. That is a fact about release timing, not a promise about the future.

Upgrade cost is documented rather than implied. The README says to see UPGRADING.md for details and CHANGELOG.md for what changed recently. Because the project publishes a UPGRADING file, major-version moves are expected to be read rather than guessed, and the repository also carries a phpstan-baseline.neon and a phpstan.neon.dist, which tells you static analysis is part of the project's own tooling.

The licence is MIT, stated in the README and present as LICENSE.md at the repository root. MIT is permissive: it allows commercial use and modification with the licence and copyright notice retained. That is a description of the licence text, not legal advice, and if you are shipping the package inside a proprietary product you should read LICENSE.md yourself.

Testing, if you want to run the suite, is documented in the README with Pest:

```bash
./vendor/bin/pest
```

The README also shows how to run the GitHub Actions workflow locally with act, including a matrix form that pins PHP and Laravel versions:

```bash
act -j run-tests --matrix php:8.3 --matrix laravel:"11.*" --matrix dependency-version:prefer-stable
```

## Conclusion

Adopt it if you are on Laravel, your files belong to Eloquent records, and you want named collections, per-collection disks and image conversions without writing your own upload layer. Do not adopt it if you are not on Laravel, or if you only need to move bytes to S3 and never query them. Before committing, check the UPGRADING.md notes for the major version you are crossing, confirm which filesystem disks your app actually has configured, and decide whether your queue worker will handle conversions.

## FAQ

### How do I install spatie/laravel-medialibrary?

The README does not print an install command and instead links to the documentation at spatie.be/docs/laravel-medialibrary. The package name used across the ecosystem is spatie/laravel-medialibrary, so the Composer require line follows from that.

### Can spatie/laravel-medialibrary store files on S3?

Yes. The README shows the disk name passed as the second argument to toMediaCollection, with a small file going to local and a big file going to s3 under the same downloads collection. Storage is handled by Laravel's Filesystem, so any disk Laravel supports can be used.

### What is laravel media library alternative?

The README names three: laravel-mediable, laravel-stapler and media-manager. It does not describe how they differ, so the comparison has to be made by reading each project rather than from this README.

## Sources

- [License: MIT](https://github.com/spatie/laravel-medialibrary/blob/main/LICENSE)
- [Project website](https://spatie.be/docs/laravel-medialibrary)
- [README](https://github.com/spatie/laravel-medialibrary/blob/main/README.md)
- [Releases](https://github.com/spatie/laravel-medialibrary/releases)
- [spatie/laravel-medialibrary on GitHub](https://github.com/spatie/laravel-medialibrary)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/spatie-laravel-medialibrary
