PHPackages                             crumbls/filament-media-library - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. crumbls/filament-media-library

ActiveLibrary[File &amp; Storage](/categories/file-storage)

crumbls/filament-media-library
==============================

A WordPress-like media library for Filament with central media pool and polymorphic attachments.

1.2.2(2mo ago)24MITPHPPHP ^8.2

Since Feb 10Pushed 2mo agoCompare

[ Source](https://github.com/Crumbls/filament-media-library)[ Packagist](https://packagist.org/packages/crumbls/filament-media-library)[ Docs](https://github.com/crumbls/filament-media-library)[ RSS](/packages/crumbls-filament-media-library/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (7)Versions (3)Used By (0)

Filament Media Library
======================

[](#filament-media-library)

A WordPress-style media library for Filament 5. Provides a central media pool with polymorphic attachments, so any model in your application can reference shared media through a clean pivot table.

Built on top of [Spatie Media Library](https://github.com/spatie/laravel-medialibrary) for file handling and image conversions.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 12+
- Filament 5+
- Spatie Laravel Media Library 11+

Installation
------------

[](#installation)

```
composer require crumbls/filament-media-library
```

The package auto-discovers its service provider. Migrations run automatically -- no publishing required.

Run the migrations:

```
php artisan migrate
```

Register the plugin in your Filament panel provider:

```
use Crumbls\FilamentMediaLibrary\FilamentMediaLibraryPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugins([
            FilamentMediaLibraryPlugin::make(),
        ]);
}
```

Configuration
-------------

[](#configuration)

Publish the config file to customize settings:

```
php artisan vendor:publish --tag=filament-media-library-config
```

```
// config/filament-media-library.php
return [
    // Storage disk (any disk defined in config/filesystems.php)
    'disk' => env('MEDIA_LIBRARY_DISK', 'public'),

    // Allowed upload types (glob-style MIME matching)
    'accepted_file_types' => ['image/*', 'video/*', 'application/pdf'],

    // Max upload size in kilobytes
    'max_file_size' => 10240,

    // Automatic image conversions
    'image_conversions' => [
        'thumbnail' => ['width' => 150, 'height' => 150],
        'medium'    => ['width' => 300, 'height' => 300],
        'large'     => ['width' => 1024, 'height' => 1024],
    ],

    // Named collections (for future use)
    'collections' => [],

    // Swap the Media model with your own
    'models' => [
        'media' => \Crumbls\FilamentMediaLibrary\Models\Media::class,
    ],

    // Filament navigation
    'filament' => [
        'navigation_group' => null,
        'navigation_icon'  => 'heroicon-o-photo',
        'navigation_sort'  => null,
        'navigation_label' => 'Media Library',
    ],
];
```

Usage
-----

[](#usage)

### Media Library Page

[](#media-library-page)

Once the plugin is registered, a "Media Library" page appears in your Filament panel navigation. It provides:

- Grid view of all uploaded media with thumbnails
- Drag-and-drop file uploads
- Search across title, alt text, caption, and description
- Type filtering (images, videos, documents)
- Detail modal with editable metadata (title, alt text, caption, description)
- Inline image editing (crop, rotate, flip) via CropperJS
- File URL display for easy copying

### Attaching Media to Models

[](#attaching-media-to-models)

Add the `HasMediaLibrary` trait to any Eloquent model:

```
use Crumbls\FilamentMediaLibrary\Traits\HasMediaLibrary;

class Post extends Model
{
    use HasMediaLibrary;
}
```

This gives you a full API for managing media attachments:

```
$post = Post::find(1);

// Attach a single media item
$post->attachMedia($mediaId);

// Attach with a named collection
$post->attachMedia($mediaId, 'featured-image');

// Attach with explicit order
$post->attachMedia($mediaId, 'gallery', order: 3);

// Attach multiple at once (order is auto-incremented)
$post->attachMediaMany([$mediaId1, $mediaId2, $mediaId3]);

// Attach multiple to a specific collection
$post->attachMediaMany([$mediaId1, $mediaId2], 'gallery');

// Detach media
$post->detachMedia($mediaId);

// Detach from a specific collection only
$post->detachMedia($mediaId, 'gallery');

// Sync a collection (replaces existing attachments)
$post->syncMedia([$mediaId1, $mediaId2], 'gallery');

// Query media in a collection
$galleryItems = $post->mediaInCollection('gallery')->get();

// Get all media (default collection)
$media = $post->getMediaByCollection();

// Access the relationship directly
$post->mediaLibrary; // MorphToMany, ordered by pivot 'order'
```

### MediaPicker Form Component

[](#mediapicker-form-component)

Use the `MediaPicker` in any Filament form to let users select media from the library:

```
use Crumbls\FilamentMediaLibrary\Forms\Components\MediaPicker;

public static function form(Schema $schema): Schema
{
    return $schema->components([
        MediaPicker::make('featured_image_id'),
    ]);
}
```

**Multiple selection:**

```
MediaPicker::make('gallery_ids')
    ->multiple(),
```

**Limit selections:**

```
MediaPicker::make('gallery_ids')
    ->multiple()
    ->maxItems(5),
```

**Named collection:**

```
MediaPicker::make('hero_image_id')
    ->collection('hero'),
```

The picker opens a modal with search, pagination, and thumbnail previews. Selected media is stored as an ID (single) or array of IDs (multiple) on the model.

#### Database Column Requirements

[](#database-column-requirements)

The MediaPicker stores a `media_library.id` reference directly on your model's table. You must ensure:

1. **The column exists** -- Add a nullable unsigned big integer column for the field name you pass to `MediaPicker::make()`.
2. **The column is fillable** -- Add the column name to your model's `$fillable` array.

Example migration for adding an `avatar` column to a `users` table:

```
Schema::table('users', function (Blueprint $table) {
    $table->unsignedBigInteger('avatar')->nullable();

    $table->foreign('avatar')
        ->references('id')
        ->on('media_library')
        ->nullOnDelete();
});
```

Then in your model:

```
protected $fillable = [
    // ...
    'avatar',
];
```

If you have an accessor on the same column (e.g., `getAvatarAttribute()`), remove it -- the MediaPicker needs the raw integer ID during form hydration. Use a separate method to resolve the media URL:

```
use Crumbls\FilamentMediaLibrary\Models\Media;

public function getAvatarUrl(): ?string
{
    if (! $this->avatar) {
        return null;
    }

    $media = Media::with('media')->find($this->avatar);

    return $media?->thumbnail_url;
}
```

### MediaColumn Table Column

[](#mediacolumn-table-column)

Display media thumbnails in Filament tables:

```
use Crumbls\FilamentMediaLibrary\Tables\Columns\MediaColumn;

public static function table(Table $table): Table
{
    return $table->columns([
        MediaColumn::make('media')
            ->collection('featured-image')
            ->size(50)
            ->circular(),
    ]);
}
```

**Options:**

```
// Set thumbnail size in pixels (default: 40)
MediaColumn::make('media')->size(60)

// Circular thumbnail (default: false)
MediaColumn::make('media')->circular()

// Square thumbnail (default: true)
MediaColumn::make('media')->square(false)

// Specify collection (default: 'default')
MediaColumn::make('media')->collection('gallery')
```

**Performance tip:** Eager-load the media relation to avoid N+1 queries:

```
public static function table(Table $table): Table
{
    return $table
        ->modifyQueryUsing(fn ($query) => $query->with('mediaLibrary.media'))
        ->columns([
            MediaColumn::make('media'),
        ]);
}
```

Media Model
-----------

[](#media-model)

The `Media` model wraps Spatie Media Library and provides convenient accessors:

```
use Crumbls\FilamentMediaLibrary\Models\Media;

$media = Media::find(1);

$media->file_url;       // Full URL to the original file
$media->thumbnail_url;  // Thumbnail conversion URL (falls back to original)
$media->mime_type;      // e.g. 'image/jpeg'
$media->file_size;      // Size in bytes
$media->file_name;      // Stored file name

$media->isImage();      // true for image/* MIME types
$media->isVideo();      // true for video/* MIME types
$media->isPdf();        // true for application/pdf
```

**Metadata fields:**

FieldTypeMax Length`title`string255`alt_text`string255`caption`text1000`description`text5000The model uses soft deletes. Each record gets an auto-generated UUID and tracks `uploaded_by` (foreign key to users).

Database Schema
---------------

[](#database-schema)

The package creates two tables:

**`media_library`** -- Central media records

ColumnTypeidbigint (PK)uuidstring (unique)titlestring (nullable)alt\_textstring (nullable)captiontext (nullable)descriptiontext (nullable)diskstring (default: 'public')uploaded\_byforeign key to users (nullable)created\_attimestampupdated\_attimestampdeleted\_attimestamp (soft delete)**`mediables`** -- Polymorphic pivot table

ColumnTypeidbigint (PK)media\_idforeign key to media\_librarymediable\_typestringmediable\_idbigintcollectionstring (default: 'default')orderunsigned int (default: 0)created\_attimestampupdated\_attimestampSpatie Media Library also creates its own `media` table for the underlying file records.

Publishing Assets
-----------------

[](#publishing-assets)

```
# Config
php artisan vendor:publish --tag=filament-media-library-config

# Migrations (only if you need to customize them)
php artisan vendor:publish --tag=filament-media-library-migrations

# Views (for template customization)
php artisan vendor:publish --tag=filament-media-library-views
```

Storage Disk
------------

[](#storage-disk)

Set the storage disk via environment variable or config:

```
MEDIA_LIBRARY_DISK=s3
```

Any disk defined in `config/filesystems.php` works -- `public`, `s3`, `r2`, or a custom disk.

Extending the Media Model
-------------------------

[](#extending-the-media-model)

Swap in your own Media model by updating the config:

```
// config/filament-media-library.php
'models' => [
    'media' => App\Models\CustomMedia::class,
],
```

Your custom model should extend the package's Media model:

```
namespace App\Models;

use Crumbls\FilamentMediaLibrary\Models\Media;

class CustomMedia extends Media
{
    // Add custom methods, scopes, or relationships
}
```

Security
--------

[](#security)

Uploads are validated server-side:

- **MIME type validation** -- Files are checked against `accepted_file_types` using glob-style matching (e.g., `image/*` matches `image/png`). Rejected files are not stored.
- **File size limits** -- Enforced against `max_file_size` config value.
- **Filename sanitization** -- Uploaded filenames are slugified to strip path traversal sequences, special characters, and double extensions.
- **Metadata validation** -- Title and alt text are limited to 255 characters, caption to 1000, description to 5000.

Rejected uploads dispatch an `fml-uploads-rejected` Livewire event with details for frontend notification.

Development
-----------

[](#development)

### Code Style

[](#code-style)

This project uses [Laravel Pint](https://laravel.com/docs/pint) for code formatting. A pre-push git hook runs Pint automatically and blocks pushes with style violations.

Run Pint manually:

```
vendor/bin/pint src config database tests
```

### Static Analysis

[](#static-analysis)

[Larastan](https://github.com/larastan/larastan) is configured at level 5:

```
vendor/bin/phpstan analyse --configuration=packages/filament-media-library/phpstan.neon
```

### Roadmap

[](#roadmap)

Add throttling to uploads. Add lifecycle events. Add tenant scoping.

### Testing

[](#testing)

The package uses [Pest](https://pestphp.com/) with 197 tests:

```
vendor/bin/pest --test-directory packages/filament-media-library/tests --configuration packages/filament-media-library/phpunit.xml
```

License
-------

[](#license)

MIT. See [LICENSE](LICENSE).

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance83

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

2

Last Release

87d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3020753?v=4)[Chase C. Miller](/maintainers/chasecmiller)[@chasecmiller](https://github.com/chasecmiller)

---

Top Contributors

[![chasecmiller](https://avatars.githubusercontent.com/u/3020753?v=4)](https://github.com/chasecmiller "chasecmiller (8 commits)")

---

Tags

laravelmedia libraryfilamentCrumbls

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/crumbls-filament-media-library/health.svg)

```
[![Health](https://phpackages.com/badges/crumbls-filament-media-library/health.svg)](https://phpackages.com/packages/crumbls-filament-media-library)
```

###  Alternatives

[mwguerra/filemanager

A full-featured file manager package for Laravel and Filament v5 with dual operating modes, drag-and-drop uploads, S3/MinIO support, and comprehensive security features.

718.5k1](/packages/mwguerra-filemanager)[tomatophp/filament-media-manager

Manage your media files using spatie media library with easy to use GUI for FilamentPHP

14543.9k3](/packages/tomatophp-filament-media-manager)[ercogx/laravel-filament-starter-kit

This is a Filament v3 Starter Kit for Laravel 12, designed to accelerate the development of Filament-powered applications.

401.5k](/packages/ercogx-laravel-filament-starter-kit)[josefbehr/filament-spatie-media-library-croppie

A filament form field for image upload using spatie media library and croppie.js

126.6k](/packages/josefbehr-filament-spatie-media-library-croppie)[tapp/filament-form-builder

User facing form builder using Filament components

131.2k1](/packages/tapp-filament-form-builder)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
