PHPackages                             x-laravel/spatie-medialibrary-webp-downloader - 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. [Image &amp; Media](/categories/media)
4. /
5. x-laravel/spatie-medialibrary-webp-downloader

AbandonedArchivedLibrary[Image &amp; Media](/categories/media)

x-laravel/spatie-medialibrary-webp-downloader
=============================================

Drop-in Downloader for spatie/laravel-medialibrary that converts every fetched image to WebP on the fly.

v1.0.0(2mo ago)05MITPHPPHP ^8.3CI passing

Since May 10Pushed 2mo agoCompare

[ Source](https://github.com/x-laravel/spatie-medialibrary-webp-downloader)[ Packagist](https://packagist.org/packages/x-laravel/spatie-medialibrary-webp-downloader)[ RSS](/packages/x-laravel-spatie-medialibrary-webp-downloader/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (5)Versions (2)Used By (0)

x-laravel/spatie-medialibrary-webp-downloader
=============================================

[](#x-laravelspatie-medialibrary-webp-downloader)

[![Tests](https://github.com/x-laravel/spatie-medialibrary-webp-downloader/actions/workflows/tests.yml/badge.svg)](https://github.com/x-laravel/spatie-medialibrary-webp-downloader/actions/workflows/tests.yml)[![PHP](https://camo.githubusercontent.com/c8d8dad6beb757a2b8acba331d16140813699543b88a37af0a81f20bd35f61de/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332532422d626c7565)](https://www.php.net)[![Laravel](https://camo.githubusercontent.com/42e62a9adb05b6cb16993782fd4b04b64a76be3ff5704d170001885eb70c8448/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313225323025374325323031332d726564)](https://laravel.com)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](LICENSE.md)

Drop-in `Downloader` replacement for [spatie/laravel-medialibrary](https://github.com/spatie/laravel-medialibrary) that converts every remote image into WebP on the fly while it is being downloaded.

> Unofficial plugin. Not affiliated with Spatie.

How It Works
------------

[](#how-it-works)

- Implements Spatie's `Downloader` interface — registers as the `media_downloader` in `config/media-library.php`
- Inherits the SSL &amp; User-Agent behaviour of `DefaultDownloader`, then re-encodes the temp file as WebP using `spatie/image` (the same library media-library uses internally)
- Reads Spatie's existing `media-library.image_driver` config (`gd`, `imagick`, or `vips`) — no extra wiring required, no extra dependencies pulled in
- Non-image payloads (PDF, video, archives) and configured skip MIME types pass through untouched

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

[](#requirements)

- PHP ^8.3
- Laravel ^12.0 | ^13.0
- `spatie/laravel-medialibrary ^11.0 | ^12.0`
- `spatie/image ^3.0` (already installed transitively by media-library)
- The PHP extension matching `media-library.image_driver` — `ext-gd`, `ext-imagick`, or libvips for `vips`

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

[](#installation)

```
composer require x-laravel/spatie-medialibrary-webp-downloader
```

There is **no service provider** — wiring happens through Spatie's own config.

Setup
-----

[](#setup)

Edit `config/media-library.php` and swap the downloader binding:

```
use XLaravel\Spatie\MediaLibrary\WebpDownloader\WebpDownloader;

return [
    // ...
    'media_downloader' => WebpDownloader::class,
    // ...
];
```

That's it. From now on every `addMediaFromUrl()` call passes through the WebP converter.

### Image Driver

[](#image-driver)

The driver is chosen automatically from Spatie's existing config and forwarded to `Spatie\Image\Image::useImageDriver()`:

```
// config/media-library.php
'image_driver' => env('IMAGE_DRIVER', 'gd'), // 'gd', 'imagick', or 'vips'
```

The required PHP extension (`ext-gd` / `ext-imagick`) — or libvips for `vips` — must be loaded.

### Tuning

[](#tuning)

`WebpDownloader` accepts two optional constructor arguments — all auto-resolved via the container with sensible defaults:

ArgumentDefaultMeaning`quality``85`WebP quality (0–100)`skipMimes``['image/svg+xml', 'image/gif']`MIME types that bypass conversionTo override, bind a custom instance in your own service provider:

```
use XLaravel\Spatie\MediaLibrary\WebpDownloader\WebpDownloader;

$this->app->bind(WebpDownloader::class, fn () => new WebpDownloader(
    quality: 90,
    skipMimes: ['image/svg+xml'],
));
```

Automatic File Name Correction
------------------------------

[](#automatic-file-name-correction)

`WebpDownloaderServiceProvider` is auto-discovered. It hooks `Media::creating` and rewrites the `file_name` extension to `.webp` when **all** of the following hold:

- The configured `media-library.media_downloader` is `WebpDownloader` (or a subclass)
- The persisted `mime_type` is `image/webp`
- The current `file_name` does not already end with `.webp` (case-insensitive)

So `obama.jpg` → `obama.webp` (basename preserved, extension swapped). Disk uploads of unrelated formats and media added while a different downloader is configured are never touched.

If you want to opt out, remove the provider from `config/app.php` (or set `extra.laravel.dont-discover` in your root `composer.json`) and rename manually with `->usingFileName(...)`.

Bulk Converting Existing Media
------------------------------

[](#bulk-converting-existing-media)

For repositories that already have thousands of JPEGs/PNGs sitting on disk, the package ships an Artisan command that walks the `media` table and re-encodes them in place:

```
# Dry run — shows which rows would be converted, touches nothing
php artisan media-library:webp-convert --dry-run

# Convert everything
php artisan media-library:webp-convert

# Scope to a collection or model
php artisan media-library:webp-convert --collection=images
php artisan media-library:webp-convert --model="App\Models\Post"

# Tune chunk size for large tables
php artisan media-library:webp-convert --chunk=500

# Dispatch each row as a queued job (recommended for large libraries)
php artisan media-library:webp-convert --queue
php artisan media-library:webp-convert --queue --queue-connection=redis --queue-name=media

# Incremental migration — only media added after a date
php artisan media-library:webp-convert --since=2026-04-01

# Parallel workers splitting the id range
# Terminal A:
php artisan media-library:webp-convert --id-from=1 --id-to=50000 --queue
# Terminal B:
php artisan media-library:webp-convert --id-from=50001 --id-to=100000 --queue
```

For each Media row the command:

1. Skips `image/webp`, non-image MIME types, and entries in the configured `WebpDownloader` `skipMimes`
2. Reads the file via the row's own `disk` and the `PathGenerator` resolved by Spatie (custom path generators are honoured automatically)
3. Re-encodes to WebP using `media-library.image_driver` and the quality from the container-bound `WebpDownloader` instance
4. Writes the new `.webp` file, deletes the original, and updates `file_name`, `mime_type`, and `size` on the Media row via `saveQuietly()` so the auto-rename listener doesn't fire on data we have already corrected

Existing **conversions** (thumbnails, responsive images) become stale because their source has changed. Run `php artisan media-library:regenerate` afterwards — the convert command prints a reminder when it finishes.

Testing
-------

[](#testing)

```
# Build first (once per PHP version)
DOCKER_BUILDKIT=0 docker compose --profile php83 build

# Run tests
docker compose --profile php83 up
docker compose --profile php84 up
docker compose --profile php85 up
```

License
-------

[](#license)

This package is open-sourced software licensed under the [MIT license](https://opensource.org/license/MIT).

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance85

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

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

Unknown

Total

1

Last Release

75d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2bdb64c6c087c331b8bd5906bb1aa7eb06bc83af3654a48ba8ab9da365976651?d=identicon)[X-Adam](/maintainers/X-Adam)

---

Top Contributors

[![x-adam](https://avatars.githubusercontent.com/u/60411758?v=4)](https://github.com/x-adam "x-adam (2 commits)")

---

Tags

spatielaravelimagedownloaderWebpmedialibrary

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/x-laravel-spatie-medialibrary-webp-downloader/health.svg)

```
[![Health](https://phpackages.com/badges/x-laravel-spatie-medialibrary-webp-downloader/health.svg)](https://phpackages.com/packages/x-laravel-spatie-medialibrary-webp-downloader)
```

###  Alternatives

[spatie/laravel-medialibrary

Associate files with Eloquent models

6.2k43.2M656](/packages/spatie-laravel-medialibrary)[intervention/image-laravel

Laravel Integration of Intervention Image

1588.9M201](/packages/intervention-image-laravel)[spatie/laravel-og-image

Generate OG images for your Laravel app

3643.9k](/packages/spatie-laravel-og-image)

PHPackages © 2026

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