Working with Images in Node.js: resize and crop
In modern web development, there is often a need to process images on the server side: resizing, cropping, converting formats. Node.js offers several powerful libraries for these tasks. In this article, we will cover the two most popular ones — Sharp (high performance, based on libvips) and Jimp (pure JavaScript, no native dependencies required).
1. Installation and Setup
To start, create a new project and install one of the libraries:
mkdir image-processor && cd image-processornpm init -ynpm install sharp jimp2. Resizing with Sharp
Sharp is a fast C-based library that is great for production. It supports streaming and automatic format detection.
const sharp = require('sharp');
// Simple resize to 300px width (height maintains proportions)sharp('input.jpg') .resize(300) .toFile('output-300.jpg') .then(() => console.log('Done!')) .catch(err => console.error(err));
// Forced resize to exact dimensions 200x200 (with distortion)sharp('input.jpg') .resize(200, 200, { fit: 'fill' }) .toFile('output-fill.jpg');
// Smart resize preserving proportions (center crop)sharp('input.jpg') .resize(200, 200, { fit: 'cover', position: 'centre' }) .toFile('output-cover.jpg');3. Cropping with Sharp
The extract method allows you to cut out a rectangular area of the image.
const sharp = require('sharp');
// Extract area: left=100, top=50, width=400, height=300sharp('input.jpg') .extract({ left: 100, top: 50, width: 400, height: 300 }) .toFile('cropped.jpg') .then(info => console.log('Cropped:', info));4. Working with Jimp (pure JavaScript)
Jimp is slower than Sharp but does not require compiling native modules — ideal for simple tasks or environments without permissions to install system packages.
const Jimp = require('jimp');
// resize to 300px widthJimp.read('input.jpg') .then(image => { return image .resize(300, Jimp.AUTO) // AUTO preserves proportions .writeAsync('output-jimp.jpg'); }) .then(() => console.log('Jimp resize ready')) .catch(err => console.error(err));
// crop with coordinatesJimp.read('input.jpg') .then(image => { return image .crop(100, 50, 400, 300) // x, y, width, height .writeAsync('cropped-jimp.jpg'); }) .catch(err => console.error(err));5. Combined example: resize + crop in one pass
Often you need to crop first and then resize. Sharp does this efficiently thanks to its internal pipeline:
const sharp = require('sharp');
sharp('input.jpg') .extract({ left: 50, top: 30, width: 800, height: 600 }) .resize(400, 300, { fit: 'cover' }) .toFile('result.jpg') .then(info => console.log('Final size:', info.width, 'x', info.height));6. Sharp vs Jimp Comparison
- Performance: Sharp is 5-10 times faster for large files.
- Installation: Jimp requires no native dependencies (just npm install).
- Features: Sharp supports more formats (heif, tiff, avif) and advanced filters.
- Streaming: Sharp works with Node.js streams (pipe), Jimp only with buffers.
- Recommendation: For high-load services, choose Sharp. For simple scripts or learning projects, use Jimp.
7. Working with Buffers (without saving to file)
Often images come via HTTP or are stored in memory. Both libraries support working with Buffer:
const sharp = requ Also in library
Data Validation in Rust: Libraries and Approaches
Monitoring Swift Applications: Libraries and Tools for iOS/macOS
Socket.io for JavaScript (Node.js): Complete Guide with Examples
Working with Excel in C++: Libraries and Tools for Reading and Writing
Prometheus Metrics in C# (.NET): Integration and Configuration