High performance Node.js image processing library for resizing JPEG, PNG, WebP, GIF, AVIF and TIFF images
80
Sharp provides comprehensive image resizing and geometric transformation capabilities with multiple fit strategies, interpolation methods, and precision controls.
Resize images with various fit strategies and quality controls.
/**
* Resize image to specified dimensions
* @param widthOrOptions - Target width or ResizeOptions object
* @param height - Target height in pixels (optional)
* @param options - Additional resize options (optional)
* @returns Sharp instance for chaining
*/
resize(widthOrOptions?: number | ResizeOptions, height?: number, options?: ResizeOptions): Sharp;
interface ResizeOptions {
/** Target width (alternative to first parameter) */
width?: number;
/** Target height (alternative to second parameter) */
height?: number;
/** How image should fit both dimensions */
fit?: 'cover' | 'contain' | 'fill' | 'inside' | 'outside';
/** Position/gravity when using cover or contain */
position?: number | string;
/** Background color for contain mode */
background?: string | RGBA;
/** Interpolation kernel for image reduction */
kernel?: 'nearest' | 'cubic' | 'mitchell' | 'lanczos2' | 'lanczos3' | 'mks2013' | 'mks2021';
/** Don't enlarge if smaller than target */
withoutEnlargement?: boolean;
/** Don't reduce if larger than target */
withoutReduction?: boolean;
/** Use shrink-on-load optimization */
fastShrinkOnLoad?: boolean;
}Fit Strategies:
cover - Crop to cover both dimensions (default)contain - Embed within both dimensionsfill - Stretch ignoring aspect ratioinside - Fit within dimensions preserving aspect ratiooutside - Ensure dimensions are exceeded preserving aspect ratioUsage Examples:
// Basic resize
await sharp('input.jpg')
.resize(800, 600)
.toFile('output.jpg');
// Resize with fit strategy
await sharp('input.jpg')
.resize({
width: 800,
height: 600,
fit: 'contain',
background: 'white'
})
.toFile('contain.jpg');
// Resize maintaining aspect ratio
await sharp('input.jpg')
.resize({ width: 800, fit: 'inside' })
.toFile('proportional.jpg');
// High-quality resize
await sharp('input.jpg')
.resize(400, 300, {
kernel: 'lanczos3',
withoutEnlargement: true
})
.toFile('hq-resize.jpg');Extract/crop specific regions from images.
/**
* Extract region from image (crop operation)
* @param region - Region coordinates and dimensions
* @returns Sharp instance for chaining
*/
extract(region: Region): Sharp;
interface Region {
/** Zero-indexed offset from left edge */
left: number;
/** Zero-indexed offset from top edge */
top: number;
/** Width of extracted region */
width: number;
/** Height of extracted region */
height: number;
}Usage Examples:
// Extract region
await sharp('input.jpg')
.extract({ left: 100, top: 50, width: 400, height: 300 })
.toFile('cropped.jpg');
// Pre-resize extraction (crop then resize)
await sharp('input.jpg')
.extract({ left: 0, top: 0, width: 800, height: 800 })
.resize(400, 400)
.toFile('crop-then-resize.jpg');
// Post-resize extraction (resize then crop)
await sharp('input.jpg')
.resize(1000, 1000)
.extract({ left: 250, top: 250, width: 500, height: 500 })
.toFile('resize-then-crop.jpg');Extend/pad image edges with background or derived pixels.
/**
* Extend image edges with padding
* @param extend - Padding amount or detailed options
* @returns Sharp instance for chaining
*/
extend(extend: number | ExtendOptions): Sharp;
interface ExtendOptions {
/** Padding for top edge */
top?: number;
/** Padding for left edge */
left?: number;
/** Padding for bottom edge */
bottom?: number;
/** Padding for right edge */
right?: number;
/** Background color for padding */
background?: string | RGBA;
/** How extension is done */
extendWith?: 'background' | 'copy' | 'repeat' | 'mirror';
}Extension Methods:
background - Use background color (default)copy - Copy edge pixelsrepeat - Repeat edge pixelsmirror - Mirror edge pixelsUsage Examples:
// Uniform padding
await sharp('input.jpg')
.extend(50)
.toFile('padded.jpg');
// Different padding per edge
await sharp('input.jpg')
.extend({
top: 20,
bottom: 20,
left: 50,
right: 50,
background: '#ff0000'
})
.toFile('custom-padding.jpg');
// Mirror extension
await sharp('input.jpg')
.extend({
top: 100,
bottom: 100,
extendWith: 'mirror'
})
.toFile('mirrored.jpg');Remove edges with similar colors to background.
/**
* Trim similar-colored edges from image
* @param options - Trimming options
* @returns Sharp instance for chaining
*/
trim(options?: TrimOptions): Sharp;
interface TrimOptions {
/** Background color (defaults to top-left pixel) */
background?: string | RGBA;
/** Color difference threshold (0-255) */
threshold?: number;
/** Optimize for line art vs photographic content */
lineArt?: boolean;
}Usage Examples:
// Basic trim (uses top-left pixel as background)
await sharp('input.png')
.trim()
.toFile('trimmed.png');
// Trim with specific background
await sharp('input.png')
.trim({
background: 'white',
threshold: 20
})
.toFile('white-trimmed.png');
// Trim line art
await sharp('vector-input.png')
.trim({
lineArt: true,
threshold: 5
})
.toFile('line-art-trimmed.png');Sharp provides constants for positioning and gravity options.
// Available via sharp.gravity
interface GravityEnum {
north: number;
northeast: number;
east: number;
southeast: number;
south: number;
southwest: number;
west: number;
northwest: number;
center: number;
centre: number;
}
// Available via sharp.strategy
interface StrategyEnum {
entropy: number;
attention: number;
}
// Available via sharp.kernel
interface KernelEnum {
nearest: 'nearest';
cubic: 'cubic';
mitchell: 'mitchell';
lanczos2: 'lanczos2';
lanczos3: 'lanczos3';
mks2013: 'mks2013';
mks2021: 'mks2021';
}
// Available via sharp.fit
interface FitEnum {
contain: 'contain';
cover: 'cover';
fill: 'fill';
inside: 'inside';
outside: 'outside';
}Usage Examples:
// Using gravity constants
await sharp('input.jpg')
.resize({
width: 400,
height: 400,
fit: 'cover',
position: sharp.gravity.northeast
})
.toFile('gravity-crop.jpg');
// Using strategy for smart cropping
await sharp('input.jpg')
.resize({
width: 400,
height: 400,
fit: 'cover',
position: sharp.strategy.attention
})
.toFile('smart-crop.jpg');
// Using interpolation kernel
await sharp('input.jpg')
.resize(800, 600, {
kernel: sharp.kernel.lanczos3
})
.toFile('hq-resize.jpg');Batch Processing:
const sizes = [
{ width: 200, suffix: '-thumb' },
{ width: 400, suffix: '-small' },
{ width: 800, suffix: '-medium' },
{ width: 1200, suffix: '-large' }
];
const image = sharp('input.jpg');
await Promise.all(
sizes.map(size =>
image
.clone()
.resize({ width: size.width, fit: 'inside' })
.jpeg({ quality: 90 })
.toFile(`output${size.suffix}.jpg`)
)
);Responsive Images:
// Generate multiple sizes for responsive images
const generateResponsive = async (input, basename) => {
const image = sharp(input);
const metadata = await image.metadata();
const sizes = [480, 768, 1024, 1200];
return Promise.all(
sizes.map(width =>
image
.clone()
.resize({
width: Math.min(width, metadata.width),
fit: 'inside',
withoutEnlargement: true
})
.webp({ quality: 85 })
.toFile(`${basename}-${width}w.webp`)
)
);
};Install with Tessl CLI
npx tessl i tessl/npm-sharpdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10