High performance Node.js image processing library for resizing JPEG, PNG, WebP, GIF, AVIF and TIFF images
80
Sharp supports comprehensive output options with format-specific optimizations and extensive metadata control.
Write processed images to files or buffers.
/**
* Write image to file with automatic format detection
* @param fileOut - Output file path
* @param callback - Optional callback function
* @returns Promise resolving to output information
*/
toFile(fileOut: string, callback?: (err: Error, info: OutputInfo) => void): Promise<OutputInfo>;
/**
* Write image to Buffer
* @param options - Buffer output options
* @returns Promise resolving to Buffer
*/
toBuffer(options?: BufferOptions): Promise<Buffer>;
/**
* Write image to Buffer with metadata
* @param options - Buffer output options with resolveWithObject: true
* @returns Promise resolving to object with data and info
*/
toBuffer(options: { resolveWithObject: true }): Promise<{ data: Buffer; info: OutputInfo }>;
interface OutputInfo {
/** Output format identifier */
format: string;
/** Output file size in bytes */
size: number;
/** Output width in pixels */
width: number;
/** Output height in pixels */
height: number;
/** Number of channels in output */
channels: number;
/** Whether premultiplication was used */
premultiplied: boolean;
/** Crop offset (when using crop strategies) */
cropOffsetLeft?: number;
cropOffsetTop?: number;
/** Trim offset (when using trim) */
trimOffsetLeft?: number;
trimOffsetTop?: number;
}
interface BufferOptions {
/** Resolve with object containing data and info */
resolveWithObject?: boolean;
}Usage Examples:
// Write to file (format auto-detected from extension)
const info = await sharp('input.jpg')
.resize(800, 600)
.toFile('output.webp');
console.log(`Output: ${info.width}x${info.height}, ${info.size} bytes`);
// Write to buffer
const buffer = await sharp('input.png')
.jpeg({ quality: 90 })
.toBuffer();
// Write to buffer with metadata
const { data, info } = await sharp('input.tiff')
.png()
.toBuffer({ resolveWithObject: true });High-quality JPEG output with extensive compression controls.
/**
* Configure JPEG output options
* @param options - JPEG-specific options
* @returns Sharp instance for chaining
*/
jpeg(options?: JpegOptions): Sharp;
interface JpegOptions {
/** Quality level (1-100, default 80) */
quality?: number;
/** Use progressive encoding */
progressive?: boolean;
/** Chroma subsampling ('4:2:0' or '4:4:4') */
chromaSubsampling?: string;
/** Apply trellis quantization */
trellisQuantisation?: boolean;
/** Apply overshoot deringing */
overshootDeringing?: boolean;
/** Optimize progressive scans */
optimiseScans?: boolean;
optimizeScans?: boolean;
/** Optimize Huffman coding tables */
optimiseCoding?: boolean;
optimizeCoding?: boolean;
/** Quantization table (0-8) */
quantisationTable?: number;
quantizationTable?: number;
/** Use mozjpeg encoder defaults */
mozjpeg?: boolean;
}Usage Examples:
// High-quality JPEG
await sharp('input.png')
.jpeg({
quality: 95,
progressive: true,
optimizeCoding: true
})
.toFile('high-quality.jpg');
// Web-optimized JPEG
await sharp('input.tiff')
.jpeg({
quality: 85,
progressive: true,
mozjpeg: true
})
.toFile('web-optimized.jpg');
// Print-quality JPEG
await sharp('input.raw')
.jpeg({
quality: 100,
chromaSubsampling: '4:4:4',
trellisQuantisation: true
})
.toFile('print-quality.jpg');Lossless PNG output with compression and palette options.
/**
* Configure PNG output options
* @param options - PNG-specific options
* @returns Sharp instance for chaining
*/
png(options?: PngOptions): Sharp;
interface PngOptions {
/** Use progressive (interlaced) encoding */
progressive?: boolean;
/** zlib compression level (0-9, default 6) */
compressionLevel?: number;
/** Use adaptive row filtering */
adaptiveFiltering?: boolean;
/** Quality for palette reduction (0-100, default 100) */
quality?: number;
/** CPU effort for file size reduction (1-10, default 7) */
effort?: number;
/** Use palette-based encoding */
palette?: boolean;
/** Maximum palette colors */
colours?: number;
colors?: number;
/** Floyd-Steinberg dithering level */
dither?: number;
}Usage Examples:
// High compression PNG
await sharp('input.jpg')
.png({
compressionLevel: 9,
adaptiveFiltering: true,
effort: 10
})
.toFile('compressed.png');
// Palette PNG for web
await sharp('input.jpg')
.png({
palette: true,
colors: 256,
quality: 90,
dither: 1.0
})
.toFile('palette.png');
// Progressive PNG
await sharp('input.bmp')
.png({
progressive: true,
compressionLevel: 6
})
.toFile('progressive.png');Modern WebP format with excellent compression and quality.
/**
* Configure WebP output options
* @param options - WebP-specific options
* @returns Sharp instance for chaining
*/
webp(options?: WebpOptions): Sharp;
interface WebpOptions {
/** Quality level (1-100, default 80) */
quality?: number;
/** Alpha channel quality (0-100, default 100) */
alphaQuality?: number;
/** Use lossless compression */
lossless?: boolean;
/** Use near-lossless compression */
nearLossless?: boolean;
/** Use smart chroma subsampling */
smartSubsample?: boolean;
/** Auto-adjust deblocking filter */
smartDeblock?: boolean;
/** CPU effort for file size reduction (0-6, default 4) */
effort?: number;
/** Animation loop count */
loop?: number;
/** Frame delays for animation */
delay?: number | number[];
/** Minimize animation file size */
minSize?: boolean;
/** Allow mixed lossy/lossless frames */
mixed?: boolean;
/** Encoding preset */
preset?: 'default' | 'photo' | 'picture' | 'drawing' | 'icon' | 'text';
}Usage Examples:
// High-quality WebP
await sharp('input.jpg')
.webp({
quality: 90,
effort: 6
})
.toFile('high-quality.webp');
// Lossless WebP
await sharp('input.png')
.webp({
lossless: true
})
.toFile('lossless.webp');
// Animated WebP
await sharp('frames/*.jpg')
.webp({
quality: 80,
loop: 0,
delay: [100, 200, 150]
})
.toFile('animated.webp');Next-generation AVIF format with superior compression.
/**
* Configure AVIF output options
* @param options - AVIF-specific options
* @returns Sharp instance for chaining
*/
avif(options?: AvifOptions): Sharp;
interface AvifOptions {
/** Quality level (1-100, default 50) */
quality?: number;
/** Use lossless compression */
lossless?: boolean;
/** CPU effort (0-9, default 4) */
effort?: number;
/** Chroma subsampling ('4:2:0' or '4:4:4') */
chromaSubsampling?: string;
/** Bit depth (8, 10, or 12) */
bitdepth?: 8 | 10 | 12;
}Usage Examples:
// Standard AVIF
await sharp('input.jpg')
.avif({
quality: 60,
effort: 6
})
.toFile('compressed.avif');
// High bit-depth AVIF
await sharp('input.tiff')
.avif({
quality: 80,
bitdepth: 10,
effort: 9
})
.toFile('hdr.avif');Professional TIFF output with multiple compression options.
/**
* Configure TIFF output options
* @param options - TIFF-specific options
* @returns Sharp instance for chaining
*/
tiff(options?: TiffOptions): Sharp;
interface TiffOptions {
/** Quality for JPEG compression (1-100, default 80) */
quality?: number;
/** Compression method */
compression?: 'none' | 'jpeg' | 'deflate' | 'packbits' | 'ccittfax4' | 'lzw' | 'webp' | 'zstd' | 'jp2k';
/** Compression predictor */
predictor?: 'none' | 'horizontal' | 'float';
/** Create image pyramid */
pyramid?: boolean;
/** Create tiled TIFF */
tile?: boolean;
/** Tile width (default 256) */
tileWidth?: number;
/** Tile height (default 256) */
tileHeight?: number;
/** Horizontal resolution (pixels/mm) */
xres?: number;
/** Vertical resolution (pixels/mm) */
yres?: number;
/** Resolution unit */
resolutionUnit?: 'inch' | 'cm';
/** Bit depth reduction */
bitdepth?: 1 | 2 | 4 | 8;
/** Use miniswhite for 1-bit images */
miniswhite?: boolean;
}Usage Examples:
// Compressed TIFF
await sharp('input.jpg')
.tiff({
compression: 'lzw',
predictor: 'horizontal'
})
.toFile('compressed.tiff');
// High-resolution print TIFF
await sharp('input.raw')
.tiff({
compression: 'none',
xres: 300,
yres: 300,
resolutionUnit: 'inch'
})
.toFile('print.tiff');
// Tiled TIFF for large images
await sharp('huge-input.tiff')
.tiff({
tile: true,
tileWidth: 512,
tileHeight: 512,
compression: 'jpeg',
quality: 90
})
.toFile('tiled.tiff');Sharp supports many other formats with specific options.
/**
* Configure HEIF/HEIC output
*/
heif(options?: HeifOptions): Sharp;
/**
* Configure GIF output (requires ImageMagick)
*/
gif(options?: GifOptions): Sharp;
/**
* Configure JPEG 2000 output
*/
jp2(options?: Jp2Options): Sharp;
/**
* Configure JPEG-XL output (experimental)
*/
jxl(options?: JxlOptions): Sharp;
/**
* Configure raw pixel output
*/
raw(options?: RawOptions): Sharp;
interface FormatInfo {
id: string;
input: { file: boolean; buffer: boolean; stream: boolean };
output: { file: boolean; buffer: boolean; stream: boolean };
}
/**
* Force specific output format
*/
toFormat(format: string | FormatInfo, options?: any): Sharp;Generate tiled image pyramids for web viewing.
/**
* Generate tiled pyramid output
* @param options - Tile generation options
* @returns Sharp instance for chaining
*/
tile(options?: TileOptions): Sharp;
interface TileOptions {
/** Tile size in pixels (1-8192, default 256) */
size?: number;
/** Tile overlap in pixels (0-8192, default 0) */
overlap?: number;
/** Tile rotation angle (multiple of 90) */
angle?: number;
/** Background color */
background?: string | RGBA;
/** Pyramid depth */
depth?: 'onepixel' | 'onetile' | 'one';
/** Skip blank tiles threshold */
skipBlanks?: number;
/** Container format */
container?: 'fs' | 'zip';
/** Tile layout */
layout?: 'dz' | 'iiif' | 'iiif3' | 'zoomify' | 'google';
/** Center tiles */
centre?: boolean;
center?: boolean;
/** IIIF identifier */
id?: string;
/** Zip directory basename */
basename?: string;
}Usage Examples:
// Deep Zoom tiles
await sharp('large-image.jpg')
.tile({
size: 512,
overlap: 2,
layout: 'dz'
})
.toFile('tiles.dzi');
// IIIF tiles
await sharp('manuscript.tiff')
.tile({
layout: 'iiif',
id: 'https://example.com/iiif/manuscript',
size: 256
})
.toFile('iiif-tiles');
// Zoomify tiles
await sharp('artwork.png')
.tile({
layout: 'zoomify',
background: 'white'
})
.toFile('zoomify-tiles');Control metadata preservation and modification in output images.
/**
* Keep all metadata from input
*/
keepMetadata(): Sharp;
/**
* Keep EXIF metadata
*/
keepExif(): Sharp;
/**
* Set EXIF metadata
*/
withExif(exif: Exif): Sharp;
/**
* Merge EXIF metadata with existing
*/
withExifMerge(exif: Exif): Sharp;
/**
* Keep ICC color profile
*/
keepIccProfile(): Sharp;
/**
* Set ICC color profile
*/
withIccProfile(profile: string, options?: WithIccProfileOptions): Sharp;
/**
* Keep XMP metadata
*/
keepXmp(): Sharp;
/**
* Set XMP metadata
*/
withXmp(xmp: string): Sharp;
/**
* Set custom metadata
*/
withMetadata(metadata?: WriteableMetadata): Sharp;
interface WriteableMetadata {
/** Image density (DPI) */
density?: number;
/** EXIF orientation (1-8) */
orientation?: number;
}Usage Examples:
// Preserve all metadata
await sharp('input.jpg')
.resize(800, 600)
.keepMetadata()
.toFile('resized-with-metadata.jpg');
// Custom EXIF data
await sharp('input.jpg')
.withExif({
IFD0: {
Copyright: '© 2024 Example Corp',
Artist: 'Jane Photographer'
}
})
.jpeg()
.toFile('with-copyright.jpg');
// Set color profile
await sharp('input.jpg')
.withIccProfile('srgb')
.toFile('color-managed.jpg');Format Selection Guide:
Quality vs Size Trade-offs:
const optimizeForWeb = async (input, output) => {
const { width } = await sharp(input).metadata();
// Choose format and quality based on content and size
if (width > 1920) {
// Large images: prioritize compression
await sharp(input)
.resize({ width: 1920, fit: 'inside' })
.webp({ quality: 80, effort: 6 })
.toFile(output);
} else {
// Smaller images: balance quality and size
await sharp(input)
.webp({ quality: 90, effort: 4 })
.toFile(output);
}
};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