How to compress and optimize images at build time with Sharp and Squoosh
Sharp API, Squoosh CLI, build pipeline integration, quality settings, metadata stripping, batch processing, Vite image plugins, on-demand vs build-time optimization
Build-Time Image Optimization
Manual image compression doesn't scale. Automate it at build time so every image is optimized on every deploy, without developer effort.
Sharp is the fastest Node.js image processing library. Use it in build scripts or as a Vite/Webpack plugin:
import sharp from 'sharp';
import { glob } from 'glob';
const images = await glob('src/images/*.{jpg,png}');
for (const input of images) {
const base = input.replace(/\.(jpg|png)$/, '');
// WebP
await sharp(input).webp({ quality: 80 }).toFile(`${base}.webp`);
// AVIF
await sharp(input).avif({ quality: 60 }).toFile(`${base}.avif`);
// Resize for srcset variants
await sharp(input).resize(800).webp({ quality: 80 }).toFile(`${base}-800.webp`);
}Quality settings: 80 for WebP and 55–65 for AVIF produce visually indistinguishable results from lossless at 30–70% smaller file sizes. Strip metadata (EXIF, color profiles) to save an additional 10–20KB per photo:
sharp(input).withMetadata(false).webp({ quality: 80 })For Vite projects, vite-imagetools handles this declaratively:
import heroUrl from './hero.jpg?format=webp&width=1200';Image CDNs (Cloudinary, Imgix) replace build-time processing with URL-based transforms — useful when you can't control the build pipeline or when images are user-uploaded.
