DEV Community

Cover image for On-the-Fly Image Compression Comparison Between NestJS and Laravel
Devops Makeit-run
Devops Makeit-run

Posted on • Originally published at make-it.run

On-the-Fly Image Compression Comparison Between NestJS and Laravel

On-the-Fly Image Compression: NestJS vs. Laravel

Introduction

Image compression is crucial in modern web applications where high-performance, responsive user experiences are expected. Efficiently delivering minified images can dramatically reduce bandwidth, accelerate page loads, and improve SEO. Two popular frameworks for backend API development are NestJS (Node.js/TypeScript) and Laravel (PHP), each with robust ecosystems and communities. In this article, we'll explore on-the-fly image compression solutions in NestJS and Laravel, providing practical code examples and an in-depth comparison in terms of performance, code complexity, and developer experience.

What You'll Learn


Key differences between NestJS and Laravel for on-the-fly image compression
Setting up high-performance image compression in both frameworks
Code samples for real-time image compression APIs
Pros, cons, and performance benchmarks
Recommendations for optimal use cases

The Role of On-the-fly Image Compression

Image minimization as part of a web API's delivery pipeline often leverages libraries like Sharp (Node.js) or Intervention Image (PHP). Such solutions:


Reduce payload sizes
Adapt image output for different clients (responsive images)
Support modern formats (e.g. WebP, AVIF)

Delivering images on-the-fly avoids maintaining numerous pre-generated variants, sharply reducing storage costs and enabling real-time optimization. According to Google's PageSpeed Insights, serving optimized images can lead to over 50% improvement in load times for image-heavy pages.

Implementing On-the-fly Image Compression in NestJS

Step 1: Set Up a NestJS Project

First, create a new NestJS application:

npx @nestjs/cli new nest-image-compressor
cd nest-image-compressor
Enter fullscreen mode Exit fullscreen mode

Step 2: Install Sharp

Sharp is the de facto image processing library for Node.js.

npm install sharp
Enter fullscreen mode Exit fullscreen mode

Step 3: Create the Image Compression Endpoint

// src/image/image.controller.ts
import { Controller, Get, Query, Res } from '@nestjs/common';
import { Response } from 'express';
import * as fs from 'fs';
import * as path from 'path';
import * as sharp from 'sharp';

@Controller('image')
export class ImageController {
  @Get('compress')
  async compressImage(
    @Query('filename') filename: string,
    @Query('w') width: string,
    @Res() res: Response
  ) {
    const filePath = path.join(__dirname, '../../images', filename);
    if (!fs.existsSync(filePath)) {
      return res.status(404).send('Image not found');
    }
    const w = width ? parseInt(width) : null;

    res.set('Content-Type', 'image/jpeg');
    const transformer = sharp(filePath).jpeg({ quality: 70 });
    if (w) {
      transformer.resize(w);
    }
    transformer.pipe(res);
  }
}
Enter fullscreen mode Exit fullscreen mode

Add the controller to your module. The endpoint /image/compress?filename=cat.jpg&w=400 will minify and resize the image instantly and stream it back to the client.

  • No intermediate files
  • Uses Node.js streams for speed
  • Handles different output qualities and sizes dynamically

Implementing Image Compression in Laravel

Step 1: Install Laravel and Intervention Image

Set up a new Laravel project and include Intervention Image:

composer create-project laravel/laravel laravel-image-compressor
cd laravel-image-compressor
composer require intervention/image
Enter fullscreen mode Exit fullscreen mode

Register the service provider (in config/app.php if using Laravel < 5.5):

'providers' => [
    // ...
    Intervention\\Image\\ImageServiceProvider::class,
],
'aliases' => [
    // ...
    'Image' => Intervention\\Image\\Facades\\Image::class,
],
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Controller

// app/Http/Controllers/ImageController.php

namespace App\\Http\\Controllers;
use Illuminate\\Http\\Request;
use Illuminate\\Support\\Facades\\Storage;
use Image; // Intervention facade

class ImageController extends Controller
{
    public function compress(Request $request)
    {
        $filename = $request->query('filename');
        $width = $request->query('w', null);
        $path = storage_path('app/public/images/' . $filename);

        if (!file_exists($path)) {
            abort(404, 'Image not found');
        }

        $image = Image::make($path)->encode('jpg', 70);
        if ($width) {
            $image->resize((int)$width, null, function ($constraint) {
                $constraint->aspectRatio();
            });
        }
        return response($image)->header('Content-Type', 'image/jpeg');
    }
}
Enter fullscreen mode Exit fullscreen mode

Route in routes/web.php:

Route::get('image/compress', [\\App\\Http\\Controllers\\ImageController::class, 'compress']);
Enter fullscreen mode Exit fullscreen mode

Highlights
Uses Intervention Image for quick compressionHandles resizing, quality, and format on-the-flyReturns immediate streamed response

Detailed Comparison: NestJS vs. Laravel

Code Comparison Table

Aspect NestJS (Sharp) Laravel (Intervention Image)
Language Node.js (TypeScript) PHP
Main Library sharp Intervention Image
Setup npm install sharp composer require intervention/image
Streaming Native Node.js streams Intervention streams to response
Async Async/await by default Supported natively in PHP 8.1+ (fiber/async limited)
Performance Very high (libvips) High, but PHP overhead
Image Formats JPEG, PNG, WebP, AVIF etc. JPEG, PNG, WebP (with GD/Imagick)
Deployment Cross-platform, Docker PHP-FPM, Apache/Nginx
Concurrency Excellent (event loop) Per-request process/thread
Best Use Case High-traffic APIs, microservices Traditional CMS, monolithic apps

Performance Benchmarks

Here are representative benchmarks observed from sharp official docs and Intervention Image GitHub:

Resource Usage

  • NestJS/Sharp uses libvips, renowned for high-speed image manipulation and low-memory usage
  • Intervention Image wraps GD or ImageMagick, which are slower and more memory-intensive

Flexibility

  • Both support resizing, format changes, and quality adjustment via endpoint query params
  • Sharp offers more image format options, including support for modern formats like AVIF

Developer Ecosystem & Maintenance


NestJS
TypeScript
Microservices

Works well in microservices, supports TypeScript, ideal for modern async programming


Laravel
PHP
Authentication
User Management
DB Migrations

Champion for rapid development in PHP, strong with built-in authentication, user management, and DB migrations

When to Choose Which?

Choose NestJS + Sharp for high-throughput, real-time image APIs, serverless-friendly workloads, and React/Vue SPA deployments. Use Laravel + Intervention Image for rapid prototyping in LAMP stacks or monolithic systems with lower concurrent image-processing demands.


Conclusion

Delivering compressed images on-the-fly is essential for modern web performance. Both NestJS (Sharp) and Laravel (Intervention Image) can be configured in just a few steps to provide robust, streaming APIs for minified images. For high-performance, concurrent workloads, especially in microservice-oriented environments, NestJS with Sharp is recommended due to its superior speed, lower memory footprint, and modern image format support. Laravel with Intervention Image is a powerful solution for traditional PHP stacks or when existing Laravel apps need quick image minification endpoints.

Next Steps


NestJS
Sharp
Laravel
Intervention Image
Docker

Resources and Guides

By understanding your app’s scalability requirements and traffic, pick the ecosystem best suited for your backend. Both examples above can be extended to support modern formats (like WebP, AVIF) and advanced features (caching, authorization) as needed.

Top comments (0)