PHPackages                             stormcelltech/mediauploader - 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. stormcelltech/mediauploader

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

stormcelltech/mediauploader
===========================

Laravel media upload and management package for Laravel with image processing, thumbnails, and multi-format support

v1.0.1(1mo ago)07↓66.7%MITPHP ^8.2|^8.3|^8.4|^8.5

Since Jul 6Compare

[ Source](https://github.com/stormcelltech/mediauploader)[ Packagist](https://packagist.org/packages/stormcelltech/mediauploader)[ RSS](/packages/stormcelltech-mediauploader/feed)WikiDiscussions Synced 1w ago

READMEChangelog (1)Dependencies (6)Versions (3)Used By (0)

Laravel MediaUploader
=====================

[](#laravel-mediauploader)

A complete media management solution for Laravel that provides a beautiful drag-and-drop uploader, media library, automatic thumbnail generation, image optimization, and a dependency-free JavaScript frontend.

MediaUploader is designed to integrate seamlessly into Laravel applications while remaining flexible enough to support custom storage disks, multi-tenancy, and custom upload workflows.

---

Features
--------

[](#features)

- 📁 Media Library
- 🖼 Automatic thumbnail generation
- 🚀 Dependency-free JavaScript uploader
- 📤 Drag &amp; Drop uploads
- 🔍 Media search and pagination
- 🎨 Blade components
- ☁️ Supports Local, Public and S3 storage
- 👤 User ownership support
- 🏢 Multi-tenant ready
- 🔒 Authentication &amp; CSRF protection
- ⚡ Automatic image optimization
- 📄 Supports images, documents, audio, video and archives
- 🔧 Fully customizable

---

Requirements
============

[](#requirements)

- PHP 8.2+
- Laravel 11+
- Node.js 20+
- npm

---

Installation
============

[](#installation)

MediaUploader consists of two packages:

- **Laravel backend package**
- **Vanilla JavaScript uploader**

Both packages are required.

---

1. Install the Laravel Package
------------------------------

[](#1-install-the-laravel-package)

```
composer require stormcelltech/mediauploader
```

---

2. Install the JavaScript Uploader
----------------------------------

[](#2-install-the-javascript-uploader)

Install the frontend uploader.

```
npm install stormcelltech-fileuploader
```

Import it once inside your application's JavaScript.

```
// resources/js/app.js

import "stormcelltech-fileuploader";
```

Compile your assets.

```
npm run dev
```

or

```
npm run build
```

> **Important**
>
> The uploader interface will not function until the JavaScript package has been installed and imported.

---

3. Publish Package Resources
----------------------------

[](#3-publish-package-resources)

Run the installer.

```
php artisan mediauploader:install
```

The installer publishes:

```
config/media-upload.php

database/migrations/xxxx_xx_xx_create_media_table.php

resources/views/components/uploader.blade.php

resources/views/components/gallery.blade.php

```

Run the migrations.

```
php artisan migrate
```

---

Quick Start
===========

[](#quick-start)

After installing both packages, you can immediately use the uploader inside any Blade view.

```

```

The component automatically renders the uploader and synchronizes the selected Media ID with a hidden input.

No additional JavaScript is required beyond importing the uploader package.

---

Next Steps
==========

[](#next-steps)

The following sections explain:

- Blade Components
- JavaScript Uploader
- Configuration
- Routes
- Controller Integration
- API Resources
- Media Collections
- Storage Configuration
- Custom Upload Endpoints
- MediaUploader Service

Blade Components
================

[](#blade-components)

MediaUploader ships with reusable Blade components that automatically render the JavaScript uploader and hidden input fields.

No additional HTML is required.

---

Single Upload
=============

[](#single-upload)

Use the uploader to store a single media ID.

```

```

When submitted, Laravel receives:

```
[
    "logo_id" => 15
]
```

---

Multiple Uploads
================

[](#multiple-uploads)

Store multiple media IDs.

```

```

Generated inputs:

```

```

Laravel receives

```
[
    "gallery" => [
        5,
        18,
        42
    ]
]
```

---

Preloading Existing Media
=========================

[](#preloading-existing-media)

Pass an existing media ID using the `value` property.

```

```

The uploader automatically loads the media from the server and displays the preview.

---

Upload Without Preview
======================

[](#upload-without-preview)

```

```

---

Hide the Media Library
======================

[](#hide-the-media-library)

Allow users to upload files without browsing existing media.

```

```

---

Custom Upload Button Text
=========================

[](#custom-upload-button-text)

```

```

---

Gallery Component
=================

[](#gallery-component)

The package also includes a gallery component.

```

```

The gallery automatically:

- Lists uploaded media
- Supports pagination
- Supports searching
- Allows selecting media
- Allows deleting media

---

Component Properties
====================

[](#component-properties)

PropertyTypeDefaultDescriptionidstringRequiredUnique uploader IDnamestringRequiredHidden input namevalueint/arraynullExisting Media ID(s)typesingle / multiplesingleUpload modetextstringSelect FileUpload button textpreviewbooltrueShow previewhideMediaTabboolfalseHide media library---

Generated HTML
==============

[](#generated-html)

The component generates HTML similar to:

```

```

The JavaScript uploader reads these data attributes automatically.

---

Hidden Inputs
=============

[](#hidden-inputs)

MediaUploader stores **Media IDs**, not file paths.

Example

```

```

For multiple uploads

```

```

This allows your controllers to simply save the media IDs in your database.

---

Example Form
============

[](#example-form)

```

    @csrf

        Save Product

```

When submitted, Laravel receives:

```
[
    "featured_image_id" => 18,

    "gallery" => [
        12,
        24,
        31
    ]
]
```

Your application only stores Media IDs, while the package manages the underlying files automatically.

Controller Integration
======================

[](#controller-integration)

MediaUploader gives you complete control over how media is uploaded, retrieved, searched, and deleted. The package provides the `MediaUploader` service, allowing you to integrate it into your own controllers.

---

Routes
======

[](#routes)

A typical route definition looks like this.

```
use App\Http\Controllers\MediaController;

Route::prefix('media')
    ->middleware(['auth'])
    ->group(function () {

        // Upload media
        Route::post('/upload', [MediaController::class, 'upload']);

        // List media
        Route::get('/list', [MediaController::class, 'GetImagesJson']);

        // Search media
        Route::get('/search/{keyword}', [MediaController::class, 'search']);

        // Retrieve a single media item
        Route::get('/{media}/get', [MediaController::class, 'getById']);

        // Update media details
        Route::put('/{medium}', [MediaController::class, 'update']);

        // Delete media
        Route::delete('/{medium}/delete', [MediaController::class, 'destroy']);
    });
```

---

Upload Controller
=================

[](#upload-controller)

Inject the `MediaUploader` service into your controller.

```
use App\Http\Resources\Media\MediaResource;
use StormcellTech\MediaUploader;

public function upload(Request $request, MediaUploader $uploader)
{
    $validator = Validator::make($request->all(), [
        'file' => 'required|file|mimes:jpeg,png,webp,gif,svg|max:5120',
    ]);

    if ($validator->fails()) {
        return response()->json([
            'status' => 400,
            'message' => $validator->errors()->first(),
        ], Response::HTTP_BAD_REQUEST);
    }

    $directory = "/uploads/media";

    $media = $uploader->store(
        $request->file('file'),
       'public' // which disk are you saving the files
        $directory,
        auth()->id() // user uploading file
    );

    return response()->json([
        'success' => true,
        'data' => new MediaResource($media),
    ]);
}
```

---

List Media
==========

[](#list-media)

Return a paginated collection.

```
public function GetImagesJson(Request $request)
{
    $media = Media::when($request->search, function ($query) use ($request) {
            $query->where('name', 'like', "%{$request->search}%");
        })
        ->latest()
        ->paginate(100);

    return response()->json([
        'status' => 200,
        'message' => 'successful',
        'data' => new MediaCollection($media),
    ]);
}
```

---

Search Media
============

[](#search-media)

```
public function search(Request $request, string $keyword)
{
    $media = Media::where('user_id', auth()->id())
        ->where('name', 'like', "%{$keyword}%")
        ->latest()
        ->paginate(100);

    return response()->json([
        'status' => 200,
        'message' => 'successful',
        'data' => new MediaCollection($media),
    ]);
}
```

---

Retrieve a Media Item
=====================

[](#retrieve-a-media-item)

```
public function getById(Media $media)
{
    return response()->json([
        'status' => 200,
        'message' => 'successful',
        'data' => new MediaResource($media),
    ]);
}
```

---

Update Media
============

[](#update-media)

The package doesn't dictate how you manage metadata. For example, renaming a file:

```
public function update(Request $request, Media $medium)
{
    $request->validate([
        'name' => ['required', 'string'],
    ]);

    $medium->update([
        'name' => $request->name,
    ]);

    return response()->json([
        'status' => 200,
        'message' => 'successful',
        'data' => new MediaResource($medium->refresh()),
    ]);
}
```

---

Delete Media
============

[](#delete-media)

Delete both the physical files and the database record.

```
use StormcellTech\MediaUploader;

public function destroy(Media $medium, MediaUploader $uploader)
{
    $uploader->deleteMedia(
        $medium->filename,
        $medium->thumbnails ?? [],
        $medium->disk ?? 'public'
    );

    $medium->delete();

    return response()->json([
        'status' => 200,
        'message' => 'Image deleted successfully',
    ]);
}
```

---

Media Resource
==============

[](#media-resource)

The JavaScript uploader consumes a JSON resource similar to the following.

```
class MediaResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [

            'id' => $this->id,

            'filename' => $this->name,

            'mime' => $this->mime_type,

            'extension' => $this->extension,

            'full_url' => $this->getUrl(),

            'thumb' => $this->getUrl('300x300'),

            'size' => Number::fileSize($this->size ?? 0, 2),

            'created_at' => (string) $this->created_at->shortAbsoluteDiffForHumans(),

            'updated_at' => (string) $this->updated_at->shortAbsoluteDiffForHumans(),
        ];
    }
}
```

---

Media Collection
================

[](#media-collection)

Media library responses should return a paginated collection.

```
class MediaCollection extends ResourceCollection
{
    public function toArray(Request $request): array
    {
        return [

            'current_page' => $this->currentPage(),

            'data' => $this->collection,

            'first_page_url' => $this->url(1),

            'from' => $this->firstItem(),

            'last_page' => $this->lastPage(),

            'last_page_url' => $this->url($this->lastPage()),

            'next_page_url' => $this->nextPageUrl(),

            'path' => $this->path(),

            'per_page' => $this->perPage(),

            'prev_page_url' => $this->previousPageUrl(),

            'to' => $this->lastItem(),

            'total' => $this->total(),
        ];
    }
}
```

---

Upload Response
===============

[](#upload-response)

A successful upload should return a resource similar to the following.

```
{
  "success": true,
  "data": {
    "id": 15,
    "filename": "logo.png",
    "mime": "image/png",
    "extension": "png",
    "full_url": "https://example.com/storage/uploads/logo.png",
    "thumb": "https://example.com/storage/uploads/300x300/logo.png",
    "size": "324 KB",
    "created_at": "2 seconds ago",
    "updated_at": "2 seconds ago"
  }
}
```

The JavaScript uploader uses this response to automatically update previews, hidden input values, and the media library without requiring additional JavaScript.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance90

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

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

Total

2

Last Release

46d ago

PHP version history (2 changes)v1.0.0PHP ^8.1

v1.0.1PHP ^8.2|^8.3|^8.4|^8.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/628640fb56699120736e09c874fdd4b5e1b0115c73ef1dc240ed07cc1fcc8aaf?d=identicon)[stormcelltech](/maintainers/stormcelltech)

---

Tags

laravelimageprocessingmediauploadThumbnailsintervention image

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/stormcelltech-mediauploader/health.svg)

```
[![Health](https://phpackages.com/badges/stormcelltech-mediauploader/health.svg)](https://phpackages.com/packages/stormcelltech-mediauploader)
```

###  Alternatives

[unopim/unopim

UnoPim Laravel PIM

10.8k2.5k](/packages/unopim-unopim)[bagisto/bagisto

Bagisto Laravel E-Commerce

28.0k175.2k9](/packages/bagisto-bagisto)[code16/sharp

Laravel Content Management Framework

79466.1k10](/packages/code16-sharp)[unisharp/laravel-filemanager

A file upload/editor intended for use with Laravel 5 to 10 and CKEditor / TinyMCE

2.2k3.6M90](/packages/unisharp-laravel-filemanager)[mostafaznv/larupload

Larupload is a ORM based file uploader for laravel to upload image, video, audio and other known files.

75487.1k6](/packages/mostafaznv-larupload)[typicms/base

A modular multilingual CMS built with Laravel, enabling developers to manage structured content like pages, news, events, and more.

1.6k20.4k](/packages/typicms-base)

PHPackages © 2026

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