next/experimental/image-optimizer-transform
API Reference for the next/experimental/image-optimizer-transform module, the standalone sharp-based image resizing and format conversion pipeline behind Next.js Image Optimization.
The next/experimental/image-optimizer-transform module exposes the transformation step of Next.js Image Optimization as a standalone Node.js module with a small dependency graph, so image resizing and format conversion (powered by sharp) can run outside the main server process.
Reference
imageOptimizerTransform
Validates an upstream image, optimizes it with sharp, and returns the result with caching metadata.
imageUpstream
| Field | Type | Description |
|---|---|---|
buffer | Buffer | The source image bytes. |
contentType | string | null | undefined | The content type reported upstream. Not trusted; the type is detected from the buffer. |
cacheControl | string | null | undefined | The upstream Cache-Control header. Used to compute maxAge. |
etag | string | The upstream ETag. Returned as upstreamEtag, and as etag when optimization is skipped. |
paramsResult
| Field | Type | Description |
|---|---|---|
href | string | The source URL of the image. Used in log and error messages. |
width | number | The target width in pixels. |
quality | number | The target quality, an integer between 1 and 100. |
mimeType | string | The requested output MIME type. An empty string means no preference. |
opts
All fields are optional.
| Field | Type | Default | Description |
|---|---|---|---|
dangerouslyAllowSVG | boolean | false | Allows SVG sources. When false, an SVG source throws an ImageError. |
minimumCacheTTL | number | 0 | The minimum maxAge of the result, in seconds. |
concurrency | number | null | undefined | The sharp thread pool size. When not a number, a default based on NODE_ENV is used. |
operationCache | boolean | null | undefined | Enables or disables the libvips operation cache. When not a boolean, sharp's default is used. |
maxInputPixels | number | undefined | Passed to sharp as limitInputPixels. When omitted, sharp's default of 268402689 is used. |
sequentialRead | boolean | null | undefined | Passed to sharp as sequentialRead. |
timeoutInSeconds | number | 7 | Per-image processing timeout. |
mozjpeg | boolean | true | Encodes JPEG output with mozjpeg. |
logger | object | undefined | A logger with error(...args) and warnOnce(message). When omitted, no logging occurs. |
These correspond to the images and experimental.imgOpt* options in next.config.js, but the defaults are not the same. For example, Next.js defaults images.minimumCacheTTL to 14400.
Returns
Promise<ImageOptimizerResult> with the following fields:
| Field | Type | Description |
|---|---|---|
buffer | Buffer | The optimized image, or the upstream image when optimization is skipped or failed. |
contentType | string | The MIME type of buffer. |
maxAge | number | The cache lifetime in seconds. |
etag | string | The ETag for the returned buffer. |
upstreamEtag | string | The ETag of the upstream image. |
optimized | boolean | true when buffer was produced by sharp, false when the upstream image was returned. |
error | unknown | Present only when optimization failed and the upstream image was returned instead. |
The function runs the following steps in order:
- Computes
maxAgeas the greater ofopts.minimumCacheTTLand the upstreamCache-Controls-maxageormax-agedirective. - Detects the content type from the magic bytes of
imageUpstream.buffer. - Throws an
ImageErrorwithstatusCode400 when the buffer is not a recognized image, or when the image is SVG andopts.dangerouslyAllowSVGisfalse. - Returns animated WebP, PNG, and GIF sources unoptimized, and calls
logger.warnOnce. - Returns SVG, ICO, ICNS, BMP, JXL, and HEIC sources unmodified.
- Selects the output type:
paramsResult.mimeTypewhen non-empty,image/jpegfor WebP or AVIF sources when no type is requested, otherwise the detected source type. - Resizes and re-encodes the image with sharp using the sharp-related
optsvalues. The output is auto-rotated according to the EXIF orientation of the source image. - On failure, returns the upstream buffer and content type with
maxAgeset toopts.minimumCacheTTLand the caught value onresult.error. The failure does not throw.
getMaxAge
Parses a Cache-Control header value and returns the s-maxage directive, or the max-age directive when s-maxage is absent, as an integer number of seconds. Returns 0 when neither directive is present or its value is not a number. This is the same parsing the image optimizer applies to upstream responses when computing maxAge.
getSharp
Loads the sharp module once, applies configuration, and returns the memoized instance.
| Parameter | Type | Description |
|---|---|---|
concurrency | number | null | undefined | The libvips thread pool size. When not a number, the default is the current concurrency divided by 4 in development or 2 in production, with a minimum of 1. |
operationCache | boolean | null | undefined | When a boolean, passed to sharp.cache() to enable or disable the libvips operation cache. |
On first load, getSharp restricts libvips image loaders to HEIF (AVIF), JPEG, GIF, PNG, SVG, TIFF, and WebP. If sharp is not installed, it throws an error that suggests running npm install --cpu=wasm32 sharp.
ImageError
The error type thrown by imageOptimizerTransform for invalid input. statusCode is preserved when it is 400 or greater. Any lower value is replaced with 500.
Good to know
sharpis required and is loaded lazily on the first call togetSharpor the first image thatimageOptimizerTransformoptimizes. The same instance is reused afterwards.- The module intentionally imports very little so it loads quickly in a separate process, such as a worker or child process. Its file location and exports are a stable public contract.
- The
contentTypefield ofimageUpstreamis not used for detection. The content type is detected from the first bytes of the buffer. - Optimization failures do not throw.
imageOptimizerTransformreturns the upstream buffer witherrorset on the result. - Animated WebP, PNG, and GIF images are returned unoptimized. SVG, ICO, ICNS, BMP, JXL, and HEIC images are always passed through without optimization.
Examples
Optimizing a fetched image
Fetch an upstream image and convert it to WebP, using the response headers as the upstream metadata.
Configuring sharp with getSharp
Use getSharp to load sharp with the same loader restrictions and concurrency limits as the Next.js image optimizer.