Sharp: High-Performance Image Processing for Node.js
Sharp handles the one job most Node.js backends need from an image library: turning uploaded JPEGs and PNGs into smaller, web-ready files fast. It runs on libvips, and the maintainers say that makes resizing 4x-5x quicker than the fastest ImageMagick or GraphicsMagick configuration. That's a real trade: a native compiled dependency for CPU headroom once you're resizing on every request instead of in a batch job.
What is Sharp?
Sharp is a Node.js module for high-speed image processing, built on the libvips C library rather than pure JavaScript. It converts and resizes JPEG, PNG, WebP, GIF, AVIF, and TIFF images, and it runs on any JavaScript runtime with Node-API v9 support, including Node.js 20.9.0 or later, Deno, and Bun. Most modern macOS, Windows, and Linux systems can run it without installing extra native dependencies.
Supported Formats and Core Operations
- โReads and converts JPEG, PNG, WebP, GIF, AVIF, and TIFF, per the README's supported format list
- โResize operations built on Lanczos resampling, so image quality holds up at smaller dimensions
- โHandles colour spaces, embedded ICC profiles, and alpha transparency channels correctly during conversion
- โRotation, cropping/extraction, compositing, and gamma correction on top of plain resizing
- โAccepts SVG as input, useful for masks and overlays in composite operations
- โWorks as a stream, so a readable image source can pipe through a transform into a writable output
Common Use Cases for Sharp
- โขGenerating multiple thumbnail sizes for a web upload pipeline
- โขConverting user-uploaded photos to WebP or AVIF before storage to cut file size
- โขResizing product images on the fly behind an API route
- โขCompositing overlays, like rounded-corner masks or watermarks, onto images server-side
Installing Sharp
Run `npm install sharp`. That's the entire install path the README shows โ no build step or config file needed for typical usage. For anything beyond that single command, the project links out to a separate installation guide on its docs site rather than covering platform-specific detail in the README itself.
Resizing and Converting Images with Code Examples
Import Sharp and start chaining operations; both ESM and CommonJS work. ```javascript // ESM import sharp from 'sharp'; // CJS const sharp = require('sharp'); ``` Resize and convert in one pass: ```javascript const output = await sharp('input.jpg') .autoOrient() .resize({ width: 200 }) .jpeg({ mozjpeg: true }) .toBuffer(); ``` Or resize straight to a file in a different format: ```javascript await sharp(inputBuffer) .resize({ width: 320, height: 240 }) .toFile('output.webp', (err, info) => { ... }); ``` Sharp also works as a stream. The README's rounded-corner example pipes a readable source through a `.composite()` call using an SVG mask and into a writable destination, without buffering the whole image in memory: ```javascript 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); ```
Performance and Quality Advantages
- โResize throughput the README frames directly against ImageMagick and GraphicsMagick, not just against doing nothing
- โCorrect handling of ICC profiles and alpha channels instead of silently flattening them
- โLanczos resampling keeps downscaled images sharp instead of muddy
- โOne chainable API covers resize, rotate, crop, composite, and gamma correction
- โRuns on Node.js, Deno, and Bun through the same Node-API v9 binding
Limitations and System Requirements
- โณIt's a native binding around libvips, not pure JavaScript โ expect platform-specific binaries and a heavier install than a JS-only package
- โณThe README doesn't describe a browser or edge-runtime story; it's built around Node-API runtimes (Node.js, Deno, Bun) on macOS, Windows, and Linux
- โณFull install and API detail live on an external docs site, not in the README, so you'll leave GitHub to get the complete picture
Alternatives to Sharp
When to Choose Sharp
Sharp fits teams already on Node.js, Deno, or Bun who need to resize, convert, or compress images inside their own request path โ an upload handler, a thumbnail job, an on-the-fly image API โ and want that work done in-process instead of shelling out to ImageMagick binaries. It's a poor fit if you need a dependency-free, pure-JavaScript image library, say for a constrained deploy target where compiling or shipping native binaries isn't an option.
Frequently Asked Questions
Sharp reads and converts JPEG, PNG, WebP, GIF, AVIF, and TIFF images. It also accepts SVG as input, for example when compositing a mask or overlay onto another image. Format conversion and resizing both run through the same chainable API.
Sharp's own README says resizing an image with Sharp is typically 4x-5x faster than the quickest ImageMagick or GraphicsMagick settings. The gap comes from its libvips backend, which skips the overhead of a full ImageMagick invocation.
Sharp works with Deno and Bun in addition to Node.js, since all three runtimes support the Node-API v9 interface Sharp is built on. On the Node.js side specifically, Sharp requires version 20.9.0 or later.
Sharp needs a JavaScript runtime with Node-API v9 support: Node.js 20.9.0 or later, Deno, or Bun. On most modern macOS, Windows, and Linux systems, the README says no additional install or runtime dependencies are required beyond that.
Sharp can create a new image from scratch instead of only transforming existing files โ you pass a `create` config with width, height, channels, and a background color rather than an input file. The README's example builds a semi-transparent red PNG this way.
Sharp is licensed under Apache-2.0, which permits commercial use, modification, and redistribution. The copyright is held by Lovell Fuller and others, as stated in the project's licensing section.
The problem it solves
Resizing or converting images inside a Node.js process usually means shelling out to an ImageMagick binary and eating its startup cost, or reaching for a pure-JS decoder that bogs down on anything past thumbnail size. That gets expensive fast under real request load. Sharp wraps libvips directly in a native Node-API module, so resize, format conversion, and compositing happen in-process at libvips' speed instead of through a child process or a slow JS-only codec.
Related repositories
Want a second opinion on sharp?
Ask an AI that can read this page โ one click and you get its take on sharp.
