PHPackages                             ghostcompiler/laravel-uploads - 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. ghostcompiler/laravel-uploads

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

ghostcompiler/laravel-uploads
=============================

Laravel Uploads for simple, secure file storage

v1.1.8(1mo ago)7465—0%2MITPHPPHP ^8.1CI passing

Since Apr 18Pushed 3d ago2 watchersCompare

[ Source](https://github.com/ghostcompiler/laravel-upload)[ Packagist](https://packagist.org/packages/ghostcompiler/laravel-uploads)[ RSS](/packages/ghostcompiler-laravel-uploads/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (10)Dependencies (3)Versions (20)Used By (0)

 [![Laravel Uploads Logo](https://camo.githubusercontent.com/7a311440d646263aeef835cc3b8d3f30b2c35f8fbf32c26ecf9a971070371ca9/68747470733a2f2f7265732e636c6f7564696e6172792e636f6d2f646a6776666c3174762f696d6167652f75706c6f61642f76313738303636363739312f6c6f676f5f6d716e716e342e706e67)](https://camo.githubusercontent.com/7a311440d646263aeef835cc3b8d3f30b2c35f8fbf32c26ecf9a971070371ca9/68747470733a2f2f7265732e636c6f7564696e6172792e636f6d2f646a6776666c3174762f696d6167652f75706c6f61642f76313738303636363739312f6c6f676f5f6d716e716e342e706e67)

 [![Laravel](https://camo.githubusercontent.com/04ac196cc9d1ede920f94387cae5075133cbd568d7b69f7b11f953f0e45e1281/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3130253230746f25323031332d4646324432303f7374796c653d666f722d7468652d6261646765266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/04ac196cc9d1ede920f94387cae5075133cbd568d7b69f7b11f953f0e45e1281/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3130253230746f25323031332d4646324432303f7374796c653d666f722d7468652d6261646765266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465) [![PHP](https://camo.githubusercontent.com/0b828fae3809f5692b3303526d43b126732078cc61f176b8f877332096c98bc0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d3737374242343f7374796c653d666f722d7468652d6261646765266c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/0b828fae3809f5692b3303526d43b126732078cc61f176b8f877332096c98bc0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d3737374242343f7374796c653d666f722d7468652d6261646765266c6f676f3d706870266c6f676f436f6c6f723d7768697465) [![Laravel Storage](https://camo.githubusercontent.com/1aebc286c490f94bc84e66b992db5cd8503c5ba61c08450301ad092e1fa3cd02/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4275696c74253230576974682d4c61726176656c25323053746f726167652d3046313732413f7374796c653d666f722d7468652d6261646765)](https://camo.githubusercontent.com/1aebc286c490f94bc84e66b992db5cd8503c5ba61c08450301ad092e1fa3cd02/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4275696c74253230576974682d4c61726176656c25323053746f726167652d3046313732413f7374796c653d666f722d7468652d6261646765)

Laravel Uploads stores files through Laravel Storage, tracks upload metadata, generates secure private file URLs, supports public disk URLs, integrates with Eloquent models, and can optionally optimize browser images.

Install
-------

[](#install)

```
composer require ghostcompiler/laravel-uploads
php artisan install:laravel-uploads
php artisan migrate
```

Use `--force` to overwrite already-published config or migration files:

```
php artisan install:laravel-uploads --force
```

By default, files are stored under `LaravelUploads` on the configured disk.

Basic Upload
------------

[](#basic-upload)

```
use GhostCompiler\LaravelUploads\Facades\Uploads;

$upload = Uploads::upload($request->file('avatar'));

$upload = Uploads::upload('avatars', $request->file('avatar'));
```

Store the upload ID on your model:

```
$user->avatar_id = $upload->id;
$user->save();
```

Delete an upload:

```
Uploads::remove($user->avatar_id);
```

The helper uses the same service:

```
$upload = GhostCompiler()->upload('avatars', $request->file('avatar'));
```

Model URLs
----------

[](#model-urls)

Add upload ID columns such as `avatar_id`, `document_id`, or `favicon_id` to your own models.

```
use GhostCompiler\LaravelUploads\Concerns\LaravelUploads;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use LaravelUploads;

    protected $uploadable = [
        'avatar_id' => [
            'name' => 'avatar',
            'id' => 'hide',
            'expiry' => 60,
        ],
    ];
}
```

Now `$user->avatar` returns the file URL. In array or JSON responses, URL fields are included by default. Set `expose => false` on a field when you do not want that URL serialized.

Customize returned values when needed:

```
public function setUploadableValue($value, string $column, array $options)
{
    if ($column === 'avatar_id') {
        return $value;
    }

    return [
        'url' => $value,
        'name' => $options['name'],
    ];
}
```

You can also define field-specific hooks when a model has multiple uploadable fields:

```
public function setAvatarUploadableValue($value)
{
    return $value;
}

public function setResumeUploadableValue($value)
{
    return [
        'url' => $value,
        'type' => 'resume',
    ];
}
```

Use `$user->avatar` for direct access. Use `$user->toArray()` or API responses when you want the configured uploadable URL fields serialized.

Public And Private URLs
-----------------------

[](#public-and-private-urls)

Private uploads generate package URLs like:

```
https://your-app.test/_laravel-uploads/file/{token}

```

Public uploads return the disk URL directly and do not create or regenerate `laravel_uploads_links` rows:

```
$upload = Uploads::upload('avatars', $request->file('avatar'), [
    'visibility' => 'public',
]);
```

For multi-tenant apps where each tenant has a different domain, register a public URL resolver:

```
use GhostCompiler\LaravelUploads\Facades\Uploads;

public function boot(): void
{
    Uploads::resolvePublicUrlsUsing(function ($upload, $disk, $path) {
        $tenant = tenant();

        return "https://{$tenant->domain}/storage/{$path}";
    });
}
```

You can also configure a resolver class:

```
'urls' => [
    'public_resolver' => App\Support\TenantUploadUrlResolver::class,
],
```

```
class TenantUploadUrlResolver
{
    public function publicUrl($upload, $disk, string $path): string
    {
        return 'https://'.tenant()->domain.'/storage/'.$path;
    }
}
```

Force a private file download with `?download=1`.

Favicon Uploads
---------------

[](#favicon-uploads)

Use the normal upload API and pass `favicon` only when the upload should be treated as a favicon:

```
$upload = Uploads::upload('favicons', $request->file('favicon'), [
    'favicon' => true,
]);
```

Existing `.ico` files are stored without conversion. JPEG, PNG, and WEBP uploads are converted into a square favicon PNG.

Other Useful APIs
-----------------

[](#other-useful-apis)

Upload multiple files:

```
$uploads = Uploads::uploadMany($request->file('documents'), 'documents');
```

Allow specific excluded extensions only when you explicitly need it:

```
$upload = Uploads::upload($request->file('script'), ['sh', 'rb']);
```

Critical extensions in `validation.never_allowed_extensions`, such as `php`, `phar`, and `phtml`, cannot be allowed with this override.

Clean expired private URL tokens:

```
php artisan ghost:laravel-uploads-clean
php artisan ghost:laravel-uploads-clean --dry-run
```

Image Optimization
------------------

[](#image-optimization)

Image optimization is disabled by default.

```
'image_optimization' => [
    'enabled' => true,
    'strict' => false,
    'quality' => 75,
    'convert_to_avif' => true,
    'max_width' => 1600,
    'max_height' => null,
]
```

When enabled, supported JPEG, PNG, and WEBP uploads try AVIF first and fall back to WEBP. Resizing preserves aspect ratio and never upscales.

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

[](#configuration)

Important config keys:

- `disk`: Laravel disk used for storage.
- `base_path`: base folder inside the disk.
- `defaults.visibility`: default `private` or `public` visibility.
- `defaults.expiry`: private URL expiry in minutes.
- `defaults.expose`: whether model serialization appends URL fields by default.
- `cache.enabled`: reuse private generated URLs until expiry.
- `cache.registry_ttl`: minutes to keep the internal cache-key registry used for deleting cached private URLs. Defaults to `60`.
- `validation.max_size`: max upload size in bytes.
- `validation.allowed_mime_types`: optional server-detected MIME allowlist.
- `validation.allowed_extensions`: optional extension allowlist.
- `validation.excluded_mime_types`: blocked MIME types.
- `validation.excluded_extensions`: blocked extensions.
- `validation.never_allowed_extensions`: critical extensions that cannot be overridden.
- `image_optimization.*`: image conversion and resize limits.
- `favicon.size`: favicon output size.
- `downloads.use_original_name`: use original filename in download headers.
- `urls.public_resolver`: optional tenant/CDN resolver for public upload URLs.
- `preview_mime_types`: MIME types allowed to open inline.
- `delete_files_with_model`: delete stored files when the model is deleted.
- `route.*`: package file-serving route settings. `route.middleware` defaults to `[]` so app `web` middleware cannot redirect image/file requests.

Full local development, path repository, validation, and security notes live in [DEVELOPER.md](DEVELOPER.md).

Release history is documented in [CHANGELOG.md](CHANGELOG.md).

Security Defaults
-----------------

[](#security-defaults)

- Upload paths are normalized and reject traversal such as `..`.
- MIME validation uses server-side detection.
- SVG is downloaded by default instead of previewed inline.
- Model URL exposure is enabled by default and can be disabled with `expose => false`.
- Public uploads use the disk URL directly.
- Private uploads use expiring package tokens.

Development And Build Environment
---------------------------------

[](#development-and-build-environment)

This package was developed using **ServBay** as the local development environment.

### Development Tool Used

[](#development-tool-used)

- Local development tool: `ServBay`
- Website: [www.servbay.com](https://www.servbay.com/)

### ServBay your development friend

[](#servbay-your-development-friend)

 [![ServBay Icon](https://camo.githubusercontent.com/105428b77c86ff428ed63af91241f05b5992274ef8e9d16b233c1ca83d9c781d/68747470733a2f2f7265732e636c6f7564696e6172792e636f6d2f646a6776666c3174762f696d6167652f75706c6f61642f76313738303636373036332f736572766261795f656463376a7a2e706e67)](https://camo.githubusercontent.com/105428b77c86ff428ed63af91241f05b5992274ef8e9d16b233c1ca83d9c781d/68747470733a2f2f7265732e636c6f7564696e6172792e636f6d2f646a6776666c3174762f696d6167652f75706c6f61642f76313738303636373036332f736572766261795f656463376a7a2e706e67)

### Testing And Build Machine

[](#testing-and-build-machine)

- Tested on: `Mac M4`
- Built on: `Mac M4`

###  Health Score

48

—

FairBetter than 94% of packages

Maintenance96

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity51

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

Total

19

Last Release

43d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/fdfc8e246731b39477bdf1668097bd52dfa52a1a9588235cbdd75d2dc7c6b927?d=identicon)[ghostcompiler](/maintainers/ghostcompiler)

---

Top Contributors

[![ghostcompiler](https://avatars.githubusercontent.com/u/269910969?v=4)](https://github.com/ghostcompiler "ghostcompiler (6 commits)")

---

Tags

laravellaravel-composerlaravel-upload-apilaravel-upload-management

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ghostcompiler-laravel-uploads/health.svg)

```
[![Health](https://phpackages.com/badges/ghostcompiler-laravel-uploads/health.svg)](https://phpackages.com/packages/ghostcompiler-laravel-uploads)
```

###  Alternatives

[illuminate/filesystem

The Illuminate Filesystem package.

15163.8M3.0k](/packages/illuminate-filesystem)[spatie/laravel-backup-server

Backup multiple applications

17119.3k1](/packages/spatie-laravel-backup-server)

PHPackages © 2026

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