← Back to archive

Repo of the Day

lovell/sharp

Published: Feb 15, 2026

Open repository ↗

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.

Summary

sharp is a Node-API image processing module that uses the libvips library to resize and convert common image formats at high speed. It runs in any JavaScript runtime that supports Node-API v9, including Node.js (>= 20.9.0), Deno, and Bun, and is licensed under Apache-2.0.

What it is useful for

sharp fits where image work needs speed without sacrificing color or alpha correctness. The README documents handling of color spaces, embedded ICC profiles, and alpha transparency, plus Lanczos resampling for resize quality.

Concrete use cases include:

  • Resizing or reformatting JPEG, PNG, WebP, AVIF, and TIFF inputs for web delivery
  • Generating multiple sized variants for responsive image layouts
  • Correcting EXIF orientation with autoOrient()
  • Producing smaller JPEGs via the mozjpeg encoder option
  • Compositing overlays, for example masking an image with an SVG to produce rounded corners
  • Streaming pipelines using Node.js readable/writable streams

Documented operations beyond resizing include rotation, extraction, compositing, and gamma correction. The README states resizing is typically 4x-5x faster than the quickest ImageMagick and GraphicsMagick settings, with that figure cited from upstream documentation.

How engineers can use it

Documented install: npm install sharp. Most modern macOS, Windows, and Linux systems do not need additional runtime dependencies; other platforms or source builds should follow the linked install guide at sharp.pixelplumbing.com.

Basic import, ESM or CJS:

import sharp from 'sharp';
// or: const sharp = require('sharp');

Resize a buffer to WebP:

await sharp(inputBuffer)
  .resize({ width: 320, height: 240 })
  .toFile('output.webp', (err, info) => { ... });

Auto-orient, resize, and re-encode a JPEG with mozjpeg:

const output = await sharp('input.jpg')
  .autoOrient()
  .resize({ width: 200 })
  .jpeg({ mozjpeg: true })
  .toBuffer();

Generate a semi-transparent PNG from scratch:

const semiTransparentRedPng = await sharp({
  create: { width: 48, height: 48, channels: 4,
    background: { r: 255, g: 0, b: 0, alpha: 0.5 } }
}).png().toBuffer();

Mask an image with an SVG inside a stream pipeline:

const roundedCorners = Buffer.from(
  '<svg><rect x="0" y="0" width="200" height="200" rx="50" ry="50"/></svg>'
);
const roundedCornerResizer = sharp()
  .resize(200, 200)
  .composite([{ input: roundedCorners, blend: 'dest-in' }])
  .png();

readableStream.pipe(roundedCornerResizer).pipe(writableStream);

Engineers should consult the linked API documentation for the full option set, supported input formats, and any platform-specific install caveats that aren't detailed in the README itself.