Skip to main content
Juliano Alves
Back to blog

Image processing pipelines with Sharp in Node.js

2 min read
By Juliano Alves

Sharp wraps libvips for fast image transforms in Node: resize, crop, composite, and output to WebP, AVIF, PNG, JPEG. It is the backbone of next/image on many deployments and works well in standalone upload workers.

Resize and format#

import sharp from 'sharp';

await sharp(inputBuffer)
  .resize(1280, 720, { fit: 'inside', withoutEnlargement: true })
  .webp({ quality: 80 })
  .toFile('out.webp');

Streaming#

For large uploads, pipe streams to avoid buffering entire files in RAM:

import fs from 'node:fs';

const pipeline = fs.createReadStream('in.jpg').pipe(
  sharp().resize(800).webp(),
);
pipeline.pipe(fs.createWriteStream('out.webp'));

Concurrency limits#

Each transform uses memory proportional to decode width/height. In worker pools, cap concurrency (e.g. p-limit) so spikes do not OOM the pod.

Metadata stripping#

Strip EXIF for privacy unless you explicitly need orientation tags—rotate() based on EXIF when retaining.

Summary#

Sharp is the pragmatic choice for server-side thumbnails and responsive variants. Tune quality/size tradeoffs with real assets and enforce memory-safe concurrency in workers.

© 2026 Juliano Alves. All rights reserved.