PHPackages                             codebyray/livewire-media-uploader - 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. codebyray/livewire-media-uploader

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

codebyray/livewire-media-uploader
=================================

Reusable Livewire v3 media uploader that integrates with Spatie Media Library and ships a publishable view.

v0.3.1(11mo ago)432MITBladePHP &gt;=8.1CI passing

Since Aug 31Pushed 1w agoCompare

[ Source](https://github.com/codebyray/livewire-media-uploader)[ Packagist](https://packagist.org/packages/codebyray/livewire-media-uploader)[ RSS](/packages/codebyray-livewire-media-uploader/feed)WikiDiscussions main Synced 4w ago

READMEChangelog (8)Dependencies (9)Versions (5)Used By (0)

[![media_uploader_screenshot](https://private-user-images.githubusercontent.com/2058181/484386060-0852d2c2-762a-440c-ad61-8c0b6939f930.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODUxMzU5NjgsIm5iZiI6MTc4NTEzNTY2OCwicGF0aCI6Ii8yMDU4MTgxLzQ4NDM4NjA2MC0wODUyZDJjMi03NjJhLTQ0MGMtYWQ2MS04YzBiNjkzOWY5MzAucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI2MDcyNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNjA3MjdUMDcwMTA4WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MWM3OTViZWYwMjNjODNhNWVlMmZjNTdmYTY5Njg2ZDk3ZTQxNDVlZmRkNDFiZTg0NTMwYzdhNDBiNTIxZDg5MSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmcmVzcG9uc2UtY29udGVudC10eXBlPWltYWdlJTJGcG5nIn0.w28oxgphUPKXrQUwlXmp5gvFxybNAU5F4A-wF4cOuog)](https://private-user-images.githubusercontent.com/2058181/484386060-0852d2c2-762a-440c-ad61-8c0b6939f930.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODUxMzU5NjgsIm5iZiI6MTc4NTEzNTY2OCwicGF0aCI6Ii8yMDU4MTgxLzQ4NDM4NjA2MC0wODUyZDJjMi03NjJhLTQ0MGMtYWQ2MS04YzBiNjkzOWY5MzAucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI2MDcyNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNjA3MjdUMDcwMTA4WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MWM3OTViZWYwMjNjODNhNWVlMmZjNTdmYTY5Njg2ZDk3ZTQxNDVlZmRkNDFiZTg0NTMwYzdhNDBiNTIxZDg5MSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmcmVzcG9uc2UtY29udGVudC10eXBlPWltYWdlJTJGcG5nIn0.w28oxgphUPKXrQUwlXmp5gvFxybNAU5F4A-wF4cOuog)Livewire Media Uploader
=======================

[](#livewire-media-uploader)

[![tests](https://github.com/codebyray/livewire-media-uploader/actions/workflows/tests.yml/badge.svg)](https://github.com/codebyray/livewire-media-uploader/actions/workflows/tests.yml)

Livewire Media Uploader is a reusable Livewire v3/v4 component that integrates seamlessly with Spatie Laravel Media Library. It ships a clean Tailwind Blade view by default (fully publishable), Bootstrap theme as an option, Alpine overlays for previews/confirmations, drag-and-drop uploads, per-file metadata (caption/description/order), configurable presets, name-conflict strategies, and optional SHA-256 duplicate detection. Drop it in, point it at a model, and you’re shipping in minutes.

---

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Publishing Assets](#publishing-assets)
- [Theme System](#theme-system-tailwind--bootstrap--custom)
    - [Dark Mode - Tailwind](#dark-mode-tailwind-theme)
    - [Custom Theme](#custom-themes)
- [Quick Start](#quick-start)
- [Usage Examples](#usage-examples)
    - [Create flow (deferred uploads)](#create-flow-deferred-uploads)
- [Configuration](#configuration)
- [Props](#props)
- [Events](#events)
- [Authorization](#authorization)
- [Model Setup (Spatie Media Library)](#model-setup-spatie-media-library)
- [Overlays &amp; UX Notes](#overlays--ux-notes)
- [Troubleshooting](#troubleshooting)
- [Roadmap](#roadmap)
- [License](#license)

---

Features
--------

[](#features)

- ✅ Livewire v3/v4 component with themeable Blade UI
    - Tailwind (default)
    - Bootstrap (optional)
    - Fully publishable and overridable
- ✅ Spatie Media Library integration (attach, list, edit meta, delete)
- ✅ **Publishable view** for per-project customization
- ✅ Drag &amp; drop uploads + progress bar
- ✅ Inline edit of **caption / description / order**
- ✅ Drag-to-reorder attached media (`order_column`)
- ✅ Name-conflict strategies: **rename | replace | skip | allow**
- ✅ Optional **exact duplicate** detection via SHA-256
- ✅ Collection → preset mapping (auto `accept` attribute)
- ✅ Image preview **overlay** + delete confirmation **modal**
- ✅ Optional **authorization hook** (`authorizeAbility`) — delegates to your app's own Gate/Policy, no auth package required
- ✅ Works with:
    - Saved model instance (`:for="$model"`)
    - String model + id (`model="user" :id="1"`)
    - FQCN, morph map alias, or dotted paths with custom namespaces
    - Local alias map

---

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

[](#requirements)

- PHP **8.2+**
- Laravel **^12.0 | ^13.0**
- Livewire **^3.0 | ^4.0**
- spatie/laravel-medialibrary **^10.12 | ^11.0**
- TailwindCSS (optional but recommended for the default view)
- Alpine.js (used by overlays/progress; see [Overlays &amp; UX Notes](#overlays--ux-notes))
- CSS depending on theme:
    - Tailwind theme → TailwindCSS (recommended)
    - Bootstrap theme → Bootstrap CSS (no Bootstrap JS required; Alpine drives modals)

> **Note on Laravel 10/11:** Earlier releases of this package listed Laravel 10 and 11 as supported. Both are now past their security-support window (Laravel 10 is EOL; Laravel 11 security support ended March 2026), and current releases of `laravel/framework` in those lines carry known, unpatched advisories — meaning a fresh `composer install` targeting either will be blocked by Composer's own audit for most consumers. Support for both has been dropped as of `v0.5.0`. If you're still running Laravel 10/11, pin this package to `v0.4.x`, but prioritize upgrading Laravel first — that's the more urgent fix.
>
> Every PHP/Laravel/Livewire combination listed above is verified on every push via [GitHub Actions](https://github.com/codebyray/livewire-media-uploader/actions/workflows/tests.yml).

---

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

[](#installation)

```
composer require codebyray/livewire-media-uploader
```

Auto-discovery will register the service provider. If you disable discovery, add:

```
// config/app.php
'providers' => [
    // ...
    Codebyray\LivewireMediaUploader\MediaUploaderServiceProvider::class,
],
```

The component is registered under **both** aliases:

- ``
- ``

---

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

[](#publishing-assets)

### Config:

[](#config)

```
php artisan vendor:publish --tag=media-uploader-config
```

### Views:

[](#views)

```
php artisan vendor:publish --tag=media-uploader-views
```

After publishing, customize the Blade at:

```
resources/views/vendor/media-uploader/themes/tailwind/media-uploader.blade.php
resources/views/vendor/media-uploader/themes/bootstrap/media-uploader.blade.php
```

Theme System (Tailwind + Bootstrap + custom)
--------------------------------------------

[](#theme-system-tailwind--bootstrap--custom)

Select the theme in config/media-uploader.php:

```
// config/media-uploader.php
return [
    'theme'  => 'tailwind', // 'tailwind' (default) or 'bootstrap'
    'themes' => [
        'tailwind'  => 'media-uploader::themes.tailwind.media-uploader',
        'bootstrap' => 'media-uploader::themes.bootstrap.media-uploader',
    ],
    // ...
];
```

### Dark mode (Tailwind theme)

[](#dark-mode-tailwind-theme)

This package’s Tailwind theme is dark-ready. Add this tiny snippet in your main layout `` to apply the user’s saved choice / system default:

```

    (() => {
        const t = localStorage.theme ?? 'system';
        const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
        const dark = t === 'dark' || (t === 'system' && prefersDark);
        if (dark) document.documentElement.classList.add('dark');
    })();

```

### Custom themes

[](#custom-themes)

- Copy an existing theme directory (e.g. themes/tailwind) to themes/custom and edit the Blade.
- Register it in the map and select it: ```
    'theme'  => 'custom',
    'themes' => [
        'tailwind'  => 'media-uploader::themes.tailwind.media-uploader',
        'bootstrap' => 'media-uploader::themes.bootstrap.media-uploader',
        'custom'    => 'media-uploader::themes.custom.media-uploader',
    ],
    ```

    > Note: The component’s Livewire + Alpine behavior is identical across themes. Only classes/markup differ. If you use the Bootstrap theme, make sure your layout includes Bootstrap CSS.

Environment variables (optional)
--------------------------------

[](#environment-variables-optional)

You can override preset limits and accepted types/mimes via .env. These map directly to config/media-uploader.php:

```
# Livewire Media Uploader (optional)

# Images
MEDIA_TYPES_IMAGES=jpg,jpeg,png,webp,avif,gif
MEDIA_MIMES_IMAGES=image/jpeg,image/png,image/webp,image/avif,image/gif
MEDIA_MAXKB_IMAGES=10240

# Documents
MEDIA_TYPES_DOCS=pdf,doc,docx,xls,xlsx,ppt,pptx,txt
MEDIA_MIMES_DOCS=application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,text/plain
MEDIA_MAXKB_DOCS=20480

# Videos
MEDIA_TYPES_VIDEOS=mp4,mov,webm
MEDIA_MIMES_VIDEOS=video/mp4,video/quicktime,video/webm
MEDIA_MAXKB_VIDEOS=102400

# Fallback preset
MEDIA_TYPES_DEFAULT=jpg,jpeg,png,webp,avif,gif,pdf,doc,docx,xls,xlsx,ppt,pptx,txt
MEDIA_MIMES_DEFAULT=image/jpeg,image/png,image/webp,image/avif,image/gif,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,text/plain
MEDIA_MAXKB_DEFAULT=10240
```

### Notes

[](#notes)

- Values are comma-separated; spaces are OK (the package trims them).
- After changing .env, run: ```
    php artisan config:clear
    ```
- The `` attribute is auto-filled from the active preset when accept\_from\_config is true (default). You can still override it per-component with the accept prop.
- If uploads fail due to size, make sure your PHP/Server limits also allow it (e.g. upload\_max\_filesize, post\_max\_size).

---

Quick Start
-----------

[](#quick-start)

1. Ensure your target Eloquent model implements `Spatie\MediaLibrary\HasMedia` and is **saved**.

    #### Model Setup (Spatie Media Library)

    [](#model-setup-spatie-media-library)

    Your model must implement `HasMedia` and be **saved** before attaching media.

    ```
    use Spatie\Image\Enums\Fit;
    use Spatie\MediaLibrary\HasMedia;
    use Spatie\MediaLibrary\InteractsWithMedia;
    use Spatie\MediaLibrary\MediaCollections\Models\Media;

    class Post extends Model implements HasMedia
    {
        use InteractsWithMedia;

        public function registerMediaCollections(): void
        {
            // Multi-file collection.
            $this->addMediaCollection('photos')
                ->useDisk('public')
                ->withResponsiveImages();

            // Single-file collection. Each new upload replaces the existing file.
            $this->addMediaCollection('avatars')
                ->singleFile();
        }

        public function registerMediaConversions(?Media $media = null): void
        {
            $this->addMediaConversion('thumb')
                ->fit(Fit::Contain, 256, 256)
                ->performOnCollections('photos', 'avatars')
                ->nonQueued();
        }
    }
    ```

    > **Multiple uploads and `singleFile()`**
    >
    > The uploader's `multiple` prop controls whether the file input allows selecting multiple files. It does **not** override Spatie Media Library's collection configuration.
    >
    > If a collection is configured with `->singleFile()`, Spatie will remove the existing media item each time another file is added. Selecting multiple files can therefore process every selected file while leaving only the last file in the collection.
    >
    > For galleries and other multi-file collections, do not use `->singleFile()`:
    >
    > ```
    > $this->addMediaCollection('photos');
    > ```
    >
    >
    >
    > Use `->singleFile()` only when the collection should contain one item, such as an avatar or logo:
    >
    > ```
    > $this->addMediaCollection('avatar')
    >     ->singleFile();
    > ```
2. Include Livewire &amp; Alpine (usually in your app layout):

    ```
    @livewireStyles
    [x-cloak]{ display:none !important; }
    @livewireScripts
    ```
3. Drop the component into your Blade:

    ```

    ```

---

Usage Examples
--------------

[](#usage-examples)

1. Pass a saved model instance

    ```

    ```
2. Short string model + id

    ```

    ```
3. Morph map alias\*\*

    ```

    ```
4. FQCN

    ```

    ```
5. Dotted path + custom namespaces

    ```

    ```
6. Local aliases (per-instance)

    ```

    ```
7. Single-file mode + hide list

    ```

    ```
8. Name conflict strategies

    ```

    ```
9. Duplicate detection by SHA-256

    ```

    ```
10. Restrict types/mimes/max size manually

    ```

    ```

### Create flow (deferred uploads)

[](#create-flow-deferred-uploads)

You can let users pick files **before** the model exists, and attach them **after** save.

**Blade (create page)**

```

```

#### Livewire component (simplified)

[](#livewire-component-simplified)

```
use App\Models\Post;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\On;
use Livewire\Component;

class PostCreate extends Component
{
    public string $title = '';
    public string $body  = '';
    public ?int $pendingPostId = null;

    protected function rules(): array
    {
        return ['title' => 'required|string|max:255', 'body' => 'required|string'];
    }

    public function save(): void
    {
        $post = Post::create([
            'user_id' => Auth::id(),
            'title'   => $this->title,
            'body'    => $this->body,
        ]);

        // Let uploaders attach everything queued for this collection
        $this->pendingPostId = $post->id;

        // Fire once per collection rendered on the page
        $this->dispatch('media:attach', model: 'post', id: $post->id, collection: 'images');
    }

    #[On('media-attached')]
    public function afterMediaAttached(string $model, string|int $id): void
    {
        if ($this->pendingPostId && (int)$id === (int)$this->pendingPostId) {
            $this->pendingPostId = null;
            $this->redirectRoute('posts.show', ['post' => $id], navigate: true);
        }
    }

    public function render() { return view('livewire.posts.post-create'); }
}
```

#### How it works

[](#how-it-works)

- On create screens, the component accepts model="post" without an id.
- Files and per-file metadata are queued locally.
- After you persist the model, dispatch: ```
    $this->dispatch('media:attach', model: 'post', id: $post->id, collection: 'images');
    ```
- The uploader resolves the saved target, attaches any queued files, and emits media-attached.

---

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

[](#configuration)

The package merges `config/media-uploader.php`:

- `accept_from_config` — if `true`, auto-fills `` from the selected preset
- `collections` — map collection name → preset key
- `presets.*.types` — extensions (comma-separated)
- `presets.*.mimes` — MIME types (comma-separated)
- `presets.*.max_kb` — max file size per file in KB

Example:

```
'collections' => [
    'avatars'     => 'images',
    'images'      => 'images',
    'attachments' => 'docs',
],
```

Show all collections together (grouped) Set `:list-all="true"` to render a grouped list of **every collection** on the target model. Items stay fully editable.

```

```

The component decides the active preset in this order:

1. Explicit `$preset` prop
2. Mapping from `collections`
3. Fallback to `default`

---

Props
-----

[](#props)

PropTypeDefaultDescription`for``Model`—Saved Eloquent model instance implementing `HasMedia`.`model``string`—Model resolver: alias, FQCN, morph alias, or dotted path.`id``intstring`—`collection``string``images`Media collection name.`disk``?string``null`Storage disk (e.g. `s3`).`multiple``bool``true`Allow selecting multiple files. The target Spatie collection must not use `singleFile()` if multiple files should be retained.`accept``?string``null``` override (otherwise may be auto from config).`showList``bool``true`Show the attached media list.`maxSizeKb``int``500` (overridden to preset’s `max_kb` if empty)Max file size (KB).`preset``?string``null`Choose a preset (`images`, `docs`, `videos`, `default`, etc.).`allowedTypes``array``[]`Extensions filter (e.g. `['jpg','png']`).`allowedMimes``array``[]`MIME filter (e.g. `['image/jpeg']`).`onNameConflict``string``rename`Strategy: `rename` | `replace` | `skip` | `allow`.`skipExactDuplicates``bool``false`Uses SHA-256 stored in `custom_properties->sha256`.`namespaces``array``['App\\Models']`Namespaces for dotted-path resolution.`aliases``array``[]`Local alias map, e.g. `['profile' => \App\Models\User::class]`.`attachedFilesTitle``string``"Current gallery"`Heading text in the list card.`listAll``bool``false`When `true`, the attached media list shows **all collections**, grouped by collection name (still editable).`authorizeAbility``?string``null`Gate/Policy ability checked against the target model before upload/delete/edit/attach. See [Authorization](#authorization).---

Events
------

[](#events)

The component dispatches browser events you can listen for:

- `media:attach` — **incoming** event the component listens for. Arguments: `model` (class/alias), `id`, optional `collection`, optional `disk`. Triggers attaching of any queued files to the now-saved target.
- `media-attached` — emitted after a successful `media:attach`. Payload: `{ model: FQCN, id: string }`.
- `media-uploaded` — emitted after an immediate upload (when a target already exists).
- `media-deleted` — emitted after deletion (`detail.id` contains the Media ID).
- `media-meta-updated` — emitted after inline metadata is saved.

Example:

```

```

---

Authorization
-------------

[](#authorization)

**By default, the component does not perform any authorization.** It verifies that a given `Media` record belongs to the resolved target model before allowing edits/deletes, but it does **not** check whether the *current user* is allowed to modify that model. It's your app's responsibility to ensure the component only renders where the user already has access (route middleware, a policy check before rendering the page, etc.).

If you'd like the component to enforce this itself, set `authorizeAbility` to a Gate/Policy ability name. It's checked against the resolved target model before every mutating action (`uploadFiles`, `remove`, `saveEdit`, and the `media:attach` event handler), using Laravel's own `Gate::authorize()` — no extra package required, and it plays nicely with anything already wired up (Policies, Gate closures, Spatie Permissions via a Gate, etc.).

```

```

With the example above, before any upload/delete/edit/attach action runs, the component calls the equivalent of `Gate::authorize('update', $post)`. If your `PostPolicy::update()` returns `false`, the action aborts with a `403` instead of proceeding.

**Notes:**

- One ability is checked for all mutating actions. If you need `delete` and `update` to map to different Policy methods, don't set `authorizeAbility` — instead wrap the component's Blade usage behind your own check, or open an issue/PR describing the use case.
- The `channel` prop used with the `media:attach` event is a namespacing convenience for routing the event to the right component instance — it is **not** an authorization boundary. Use `authorizeAbility` (or your own upstream checks) if untrusted input could influence which `model`/`id` gets dispatched to `media:attach`.
- Leaving `authorizeAbility` unset preserves the exact behavior of versions prior to `0.5.0` — this is a fully backward-compatible, opt-in addition.

---

> The list view tries `getUrl('thumb')` and falls back to `getUrl()` if no conversion is available.

---

Overlays &amp; UX Notes
-----------------------

[](#overlays--ux-notes)

- **Image Preview Overlay** (lightbox): toggled by `x-show="preview.open"`.
- **Delete Confirmation Modal**: toggled by `$wire.confirmingDeleteId !== null`.
- Add once in your layout to prevent flash-of-overlay: ```
    [x-cloak]{ display:none !important; }
    ```
- Z-index defaults: preview `z-[60]`, delete modal `z-50`. Adjust to your stack if you have higher layers.

---

Troubleshooting
---------------

[](#troubleshooting)

- **“Target model must be saved…”**
    Ensure the model exists in DB (`$model->exists === true`) before rendering the component.
- **“must implement Spatie\\MediaLibrary\\HasMedia”**
    Add `implements HasMedia` + `InteractsWithMedia` to your model.
- **Unknown model class/alias**
    If using `model="something"` + `:id`, make sure:

    - It’s a valid FQCN, morph alias, or maps via dotted path within `namespaces`, or
    - You passed a local alias via `:aliases="['something' => \App\Models\YourModel::class]`.
- **Multiple files selected, but only one remains after upload**
    Check the target model's `registerMediaCollections()` method. If the collection uses Spatie Media Library's `->singleFile()`, each new upload replaces the previous media item.

    For multiple files:

    ```
    $this->addMediaCollection('photos');
    ```

    For a collection that should contain only one file:

    ```
    $this->addMediaCollection('avatar')
      ->singleFile();
    ```
- **`accept` not applied**
    Set `accept_from_config=true` and ensure your preset has `types`/`mimes`. Or override via `accept` prop.
- **No thumbnails**
    Add a `thumb` conversion (see [Model Setup](#model-setup-spatie-media-library)).

---

Roadmap
-------

[](#roadmap)

- Show document icon instead of thumbnail in Attached media list if the file is not an image.

PRs welcome!

---

License
-------

[](#license)

**MIT** © CodebyRay (Ray Cuzzart II)

---

**Component aliases:** `media-uploader` and `media.media-uploader`
**View namespace:** `media-uploader::livewire.media-uploader`

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance78

Regular maintenance activity

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 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 ~0 days

Total

4

Last Release

339d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/56b9f090994212c557bf9e64ab54e367eacc9f614b152be8ff532cc7f3f2565b?d=identicon)[codebyray](/maintainers/codebyray)

---

Top Contributors

[![codebyray](https://avatars.githubusercontent.com/u/2058181?v=4)](https://github.com/codebyray "codebyray (18 commits)")

---

Tags

alpinejscomponentfile-uploadslaravellivewiremedia-libraryspatiespatie-laravel-medialibrarytailwindcssuploaderspatielaravellivewirefile uploadscomponentmedia librarytailwindcssalpinejsuploaderSpatie Laravel MediaLibrary

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/codebyray-livewire-media-uploader/health.svg)

```
[![Health](https://phpackages.com/badges/codebyray-livewire-media-uploader/health.svg)](https://phpackages.com/packages/codebyray-livewire-media-uploader)
```

###  Alternatives

[nasirkhan/laravel-starter

A CMS like modular Laravel starter project.

1.4k2.7k](/packages/nasirkhan-laravel-starter)[slimani/filament-media-manager

A media manager plugin for Filament.

179.7k1](/packages/slimani-filament-media-manager)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.8k](/packages/tomshaw-electricgrid)[team-nifty-gmbh/tall-datatables

Server-side rendered datatables for Laravel and Livewire

1422.0k5](/packages/team-nifty-gmbh-tall-datatables)

PHPackages © 2026

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