A while ago we released image-optimizer. In short this package can make all kinds of images smaller by stripping out metadata and applying a little bit of compression. Read this blogpost to learn more about it. Although it's pretty easy to work with the package, we felt that we could deliver a more seamless experience in Laravel apps. That's why we created our newly released laravel-image-optimizer package.

The package uses a bunch of binaries to optimize images. To learn which ones and how to install them, head over to the optimization tools section in the readme of the underlying image-optimizer package. That readme also contains info on what these tools will do to your images.

Once the laravel-image-optimizer package is installed it's laughably easy to optimize images.

If you like facades this is how you'd go about it:

use ImageOptimizer;

// the image will be replaced with an optimized version which should be smaller

// if you use a second parameter the package will not modify the original
ImageOptimizer::optimize($pathToImage, $pathToOptimizedImage);

You don't like facades you say? No problem! Just resolve a configured instance of Spatie\ImageOptimizer\OptimizerChain out of the container:


The package also contains a middleware to automatically optimize all images in a request.

Route::middleware('optimizeImages')->group(function () {
    // all images will be optimized automatically
    Route::post('upload-images', '[email protected]);

If you want to customize the chain of tools and the options being passed to them, you can do so by publishing and modifying the config file. This is the default contents:

use Spatie\ImageOptimizer\Optimizers\Svgo;
use Spatie\ImageOptimizer\Optimizers\Optipng;
use Spatie\ImageOptimizer\Optimizers\Gifsicle;
use Spatie\ImageOptimizer\Optimizers\Pngquant;
use Spatie\ImageOptimizer\Optimizers\Jpegoptim;

return [
     * When calling `optimize` the package will automatically determine which optimizers
     * should run for the given image.
    'optimizers' => [

        Jpegoptim::class => [
            '--strip-all',  // this strips out all text information such as comments and EXIF data
            '--all-progressive',  // this will make sure the resulting image is a progressive one

        Pngquant::class => [
            '--force', // required parameter for this package

        Optipng::class => [
            '-i0', // this will result in a non-interlaced, progressive scanned image
            '-o2',  // this set the optimization level to two (multiple IDAT compression trials)
            '-quiet', // required parameter for this package

        Svgo::class => [
            '--disable=cleanupIDs', // disabling because it is know to cause troubles

        Gifsicle::class => [
            '-b', // required parameter for this package
            '-O3', // this produces the slowest but best results

     * The maximum time in seconds each optimizer is allowed to run separately.
    'timeout' => 60,

     * If set to `true` all output of the optimizer binaries will be appended to the default log.
     * You can also set this to a class that implements `Psr\Log\LoggerInterface`.
    'log_optimizer_activity' => false,

To learn more about laravel-image-optimzer head over to the readme on GitHub. And be sure to check out the other Laravel package we've previously made.