Sharp vs Jimp vs Squoosh: Node.js Image Processing 2026
Sharp processes images 25x faster than squoosh-cli in benchmarks. squoosh-cli is 6x faster than jimp. But speed isn't the only dimension: Squoosh (Google's image codec project) focuses on modern codecs (WebP, AVIF, JXL), jimp is pure JavaScript with zero native dependencies, and sharp is the production workhorse used by Next.js's image optimization pipeline. For Node.js image processing in 2026, the choice depends on whether you need codec flexibility, zero native dependencies, or maximum throughput.
TL;DR
Sharp for production image processing pipelines — 9M+ weekly downloads, 25x faster than alternatives, used by Next.js next/image, native libvips with prebuilt binaries for all platforms. Jimp when you can't use native binaries (serverless environments with size limits, edge-adjacent runtimes, or zero-dependency requirements) — pure JavaScript, works anywhere. Squoosh (@squoosh/lib) when you need cutting-edge codec control — WebP, AVIF, JXL, and OxiPNG encoding with Wasm codecs that mirror what the Google Squoosh web app uses. For most production use cases, sharp is the obvious choice.
Key Takeaways
- Sharp: 9M+ weekly downloads, libvips (C library), 25x faster than squoosh, supports JPEG/PNG/WebP/AVIF/TIFF/GIF
- Jimp: 1.5M weekly downloads, pure JavaScript (no native deps), slower but universally compatible, JPEG/PNG/BMP/GIF
- Squoosh (
@squoosh/lib): Google's codec project, WebAssembly codecs, best WebP/AVIF encoding quality control - Next.js: Uses sharp for its
next/imageautomatic optimization (AVIF and WebP conversion) - Sharp benchmarks: 4-40x faster than jimp, 25x faster than squoosh-cli for resize operations
- Format support: Sharp supports WebP and AVIF natively; Jimp lacks WebP/AVIF in core; Squoosh is codec-focused
Sharp
Package: sharp
Weekly downloads: 9M+
GitHub stars: 29K
Creator: Lovell Fuller
Sharp is built on libvips — a C library designed for fast, low-memory image processing. It's the standard for any Node.js application that needs to process images at scale.
Installation
npm install sharp
# Prebuilt native binaries for macOS, Windows, Linux (x64/arm64)
# No libvips compilation needed in most environments
Basic Usage
import sharp from 'sharp';
// Resize and convert format
await sharp('input.jpg')
.resize(800, 600, {
fit: 'cover', // Crop to fill dimensions
position: 'center', // Center the crop
})
.webp({ quality: 85 })
.toFile('output.webp');
// Or to buffer (for HTTP responses):
const buffer = await sharp('input.jpg')
.resize(400) // Resize width to 400, maintain aspect ratio
.jpeg({ quality: 90, progressive: true })
.toBuffer();
Format Conversion
// Convert to WebP (40-50% smaller than JPEG at same quality)
await sharp('photo.jpg').webp({ quality: 80 }).toFile('photo.webp');
// Convert to AVIF (50-60% smaller than JPEG, better quality)
await sharp('photo.jpg')
.avif({
quality: 60, // AVIF is efficient — 60 looks like JPEG 85
effort: 6, // Encoding effort 0-9 (higher = slower, smaller)
})
.toFile('photo.avif');
// PNG with optimization
await sharp('image.png')
.png({ compressionLevel: 9, palette: true })
.toFile('optimized.png');
Pipeline for User Uploads
import sharp from 'sharp';
interface ResizeOptions {
width: number;
height: number;
quality?: number;
}
async function processUpload(
inputBuffer: Buffer,
options: ResizeOptions
): Promise<{ webp: Buffer; avif: Buffer; thumbnail: Buffer }> {
const image = sharp(inputBuffer)
.rotate() // Auto-rotate based on EXIF
.resize(options.width, options.height, {
fit: 'inside', // Don't crop, scale down to fit
withoutEnlargement: true, // Don't upscale
});
// Process multiple outputs in parallel
const [webp, avif, thumbnail] = await Promise.all([
image.clone().webp({ quality: options.quality ?? 85 }).toBuffer(),
image.clone().avif({ quality: 60 }).toBuffer(),
image.clone().resize(200, 200, { fit: 'cover' }).jpeg({ quality: 80 }).toBuffer(),
]);
return { webp, avif, thumbnail };
}
Metadata Extraction
const metadata = await sharp('image.jpg').metadata();
console.log(metadata);
// {
// width: 2000,
// height: 1500,
// format: 'jpeg',
// size: 1234567,
// exif: Buffer,
// icc: Buffer,
// orientation: 1,
// density: 72
// }
// Strip EXIF (privacy — remove GPS, camera info)
await sharp('photo.jpg')
.withMetadata(false) // Remove all metadata
.toFile('clean.jpg');
Performance Benchmark
Resize 100 images (2000x1500 → 300x200, JPEG):
Sharp: ~1.5s (60 images/second)
squoosh-cli: ~37s (2.7 images/second)
jimp: ~220s (0.45 images/second)
Sharp is ~25x faster than squoosh, ~150x faster than jimp.
Sharp in Next.js
Sharp is used by Next.js's next/image component for automatic image optimization:
// next.config.js
module.exports = {
images: {
// Next.js uses sharp to serve WebP/AVIF automatically
formats: ['image/avif', 'image/webp'],
// Based on Accept header, serves AVIF or WebP instead of JPEG
},
};
// In your component:
import Image from 'next/image';
// Sharp converts and caches the image server-side
<Image
src="/hero.jpg"
width={1200}
height={600}
alt="Hero"
priority
/>
// Browser receives WebP or AVIF automatically
Sharp Limitations
- Native binaries — can't run in true edge runtimes (Cloudflare Workers, Vercel Edge Functions)
- Requires prebuilt binaries for the target platform (CI/CD considerations)
- Not available in browser environments
Jimp
Package: jimp
Weekly downloads: 1.5M+
GitHub stars: 14K
Jimp is 100% JavaScript — no native dependencies. It's slower than sharp but runs in any environment where JavaScript runs.
Installation
npm install jimp
Basic Usage
import Jimp from 'jimp';
const image = await Jimp.read('input.jpg');
image
.resize(800, 600) // Resize
.quality(85) // JPEG quality
.greyscale() // Convert to grayscale
.write('output.jpg'); // Save
// To buffer:
const buffer = await image.getBufferAsync(Jimp.MIME_JPEG);
Image Manipulation
import Jimp from 'jimp';
const image = await Jimp.read('photo.jpg');
// Composite (overlay logo)
const logo = await Jimp.read('logo.png');
logo.resize(100, Jimp.AUTO);
image
.composite(logo, image.bitmap.width - 110, image.bitmap.height - 110)
.brightness(0.1) // Adjust brightness
.contrast(0.1) // Adjust contrast
.blur(2) // Gaussian blur
.write('branded.jpg');
Format Support
// Jimp supports: JPEG, PNG, BMP, GIF, TIFF
// Does NOT natively support: WebP, AVIF
// For WebP in Jimp, you'd need a plugin or sharp instead:
import Jimp from 'jimp';
import '@jimp/plugin-webp'; // Third-party plugin
const image = await Jimp.read('input.jpg');
await image.writeAsync('output.webp');
When Jimp Makes Sense
// Serverless environments with strict size limits:
// - AWS Lambda (ZIP size constraints)
// - Functions that can't include native binaries
// Pure Node.js scripts with no native dependency build step:
// npm install jimp && immediately works
// Simple image tasks that don't need high throughput:
// Resize one image on user upload (not bulk processing)
Jimp Limitations
- 100-150x slower than sharp for bulk operations
- No WebP or AVIF support in core
- High memory usage for large images (no streaming)
- Not suitable for production image pipelines handling scale
Squoosh
Package: @squoosh/lib
GitHub: GoogleChromeLabs/squoosh
Status: Based on Google's Squoosh project
Squoosh is Google's open-source image compression tool. The @squoosh/lib npm package brings its Wasm-based codecs to Node.js — the same codecs the squoosh.app web UI uses.
What Squoosh Does Differently
Squoosh's value isn't speed — it's codec quality control. The Wasm codecs (mozjpeg, WebP, AVIF/AV1, JXL) give you fine-grained control over encoding parameters that sharp doesn't always expose:
import { ImagePool } from '@squoosh/lib';
import { cpus } from 'os';
const imagePool = new ImagePool(cpus().length);
const imageFile = readFileSync('./input.jpg');
const image = imagePool.ingestImage(imageFile);
// Decode
await image.decoded;
// Encode with specific codec options
const { binary, extension, optionsUsed } = await image.encode({
mozjpeg: {
quality: 80,
progressive: true,
auto_subsample: true,
},
webp: {
quality: 75,
target_size: 0,
method: 4,
},
avif: {
cqLevel: 33,
speed: 8,
subsample: 1,
},
oxipng: {
level: 2,
},
});
// binary is the optimized file buffer
writeFileSync('output.webp', binary.webp.binary);
await imagePool.close();
When to Use Squoosh
Squoosh is best for build-time image optimization (not runtime), where you want maximum compression quality and don't need bulk throughput:
# CLI usage:
npx @squoosh/cli --webp '{"quality":80}' --avif '{"cqLevel":33}' *.jpg
# Outputs optimized WebP and AVIF versions of each image
# Good for:
# - Build step: compress images before deployment
# - Quality experimentation: find the right quality settings
# - Format comparison: see WebP vs AVIF file sizes for your images
Squoosh Limitations
- Much slower than sharp (25x slower for resize operations)
- Wasm-based codecs have startup overhead
@squoosh/libis less actively maintained than sharp
Comparison
| Feature | Sharp | Jimp | Squoosh |
|---|---|---|---|
| Weekly downloads | 9M | 1.5M | Low (CLI/lib) |
| Speed | Fastest (native) | Slowest (pure JS) | Medium (Wasm) |
| Native deps | Yes (libvips) | No | No (Wasm) |
| WebP support | Yes | Plugin only | Yes (mozjpeg/WebP) |
| AVIF support | Yes | No | Yes (AV1) |
| JPEG XL | No | No | Yes |
| Edge runtime | No | Limited | No |
| Next.js image | Default | No | No |
| Use case | Production pipeline | Portability | Build-time optimization |
Decision Guide
Choose Sharp if:
- Processing user uploads at scale
- You need WebP/AVIF conversion in production (Next.js, custom image service)
- Performance matters — bulk processing, CDN image optimization
- You're on a standard Node.js server (not edge runtime)
Choose Jimp if:
- You cannot use native dependencies (certain serverless environments)
- Simple one-off image tasks without performance requirements
- You need zero-native-dependency portability
- Quick prototyping before switching to sharp for production
Choose Squoosh if:
- Build-time image optimization (compress source images before deployment)
- You need fine-grained AVIF/WebP encoding control
- Quality comparison between codecs for your specific images
- You're using it as a CLI tool, not a library
Compare image processing package downloads on PkgPulse.
See the live comparison
View sharp vs. jimp vs squoosh on PkgPulse →