intervention/image-driver-vips
A high-performance libvips driver for Intervention Image 3, enabling fast, low-memory image processing for large files. It supports resizing, cropping, format conversion, and more through the familiar Intervention Image API.
sudo apt-get install libvips42 libvips-dev, then install the PHP extension (pecl install vips or your distro package) and enable it. Verify with php -m | grep vips and vips --version.composer require intervention/image intervention/image-driver-vips. For Laravel, also install intervention/image-laravel if you want the facade/config integration.php artisan vendor:publish --provider="Intervention\Image\LaravelServiceProvider". In config/image.php, point the driver at the VIPS driver class, typically \Intervention\Image\Drivers\Vips\Driver::class. Check the package README for the exact class name for your version.use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Vips\Driver;
$manager = new ImageManager(new Driver());
$image = $manager->read($request->file('photo')->getRealPath())
->cover(400, 400)
->toJpeg(82);
Storage::put("avatars/{$user->id}.jpg", (string) $image);
config/image.php, and php -m / vips --version on every environment. The first real win is large upload handling: resize/convert in a queued job instead of doing it inline in the request.ImageManager in a service provider and inject it instead of constructing drivers everywhere:$this->app->singleton(ImageManager::class, function () {
return new ImageManager(new \Intervention\Image\Drivers\Vips\Driver());
});
Bus::batch() for bulk imports and chunk the work so a single job does not exceed queue timeouts.ImageProcessor service with methods like thumbnail(), hero(), convertToWebp(), and storeVariant(). Controllers should validate and dispatch; the processor should own the Intervention calls. This keeps driver swaps and test fakes contained.cover(400, 400) for avatars, scaleDown(width: 1600) for content images, and toWebp(80) for modern output. Store variant metadata (width, height, mime, bytes) alongside the file.save($path) for local files and encode() + Storage::put() for Laravel disks. For very large outputs, prefer streaming to a temp file and uploading rather than keeping encoded bytes in memory.php -r "var_dump(extension_loaded('vips'));" plus vips --version.config/image.php, run php artisan config:clear. Under Octane, restart workers after driver/config changes.toJpeg(), otherwise you may get black or unexpected backgrounds.Storage::path() only for local disks; for remote disks use a temp file under storage/app/tmp or tmpfile(), and ensure cleanup in finally.scaleDown() before other operations and test with 50MP+ images; set memory_limit based on measured peak, not assumption.$timeout/$tries based on the largest expected file.IMAGE_DRIVER=vips|gd and a conditional binding. A missing extension should not take down every request that touches images.How can I help you explore Laravel packages today?