# How to Optimize Images in Gatsby using gatsby-plugin-sharp: Complete Options Guide

> Optimize images in Gatsby with gatsby-plugin-sharp. Explore build-time options for format, quality, compression, and visual effects via GraphQL queries and gatsby-config.js.

- Repository: [Gatsby/gatsby](https://github.com/gatsbyjs/gatsby)
- Tags: tutorial
- Published: 2026-03-06

---

**Use `gatsby-plugin-sharp` to process images at build time by configuring global defaults in [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) and applying transform options in your GraphQL queries to control formats, quality, compression, and visual effects.**

Optimizing images in Gatsby using `gatsby-plugin-sharp` provides a powerful, declarative way to resize, compress, and transform images at build time. This low-level image processing plugin wraps the Sharp library and powers both `gatsby-plugin-image` and `gatsby-transformer-sharp`, handling everything from format conversion to metadata stripping. According to the gatsbyjs/gatsby source code, the plugin processes images through a configurable pipeline defined in [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts) and [`plugin-options.ts`](https://github.com/gatsbyjs/gatsby/blob/main/plugin-options.ts), giving you granular control over every aspect of image optimization.

## Core Plugin Options in gatsby-config.js

You configure `gatsby-plugin-sharp` in your [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) file using the `options` object. These settings establish global defaults that apply across your entire site unless overridden by individual queries.

The **`defaults`** object accepts properties like `formats`, `placeholder`, `quality`, `breakpoints`, `backgroundColor`, `tracedSVGOptions`, `blurredOptions`, and format-specific options (`jpgOptions`, `pngOptions`, `webpOptions`, `avifOptions`). These values are stored in [`plugin-options.ts`](https://github.com/gatsbyjs/gatsby/blob/main/plugin-options.ts) (lines 20–28) and merged with query-level arguments via the `healOptions` function.

Other critical global settings include:

- **`defaultQuality`**: Sets the base quality to `50` when no explicit quality is provided in a query.
- **`stripMetadata`**: Defaults to `true`, removing EXIF and ICC data to reduce file size. Set to `false` for photography portfolios requiring metadata preservation.
- **`useMozJpeg`**: Enables the faster, better-compression **mozjpeg** encoder when set to `true` (default follows `GATSBY_JPEG_ENCODER` environment variable).
- **`failOn`**: Controls Sharp's error-handling mode with options `'warning'` (default), `'error'`, or `'none'`.
- **`lazyImageGeneration`**: When `true` (default), defers image creation to runtime.

Configure these in your [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js):

```javascript
module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-sharp`,
      options: {
        defaults: {
          formats: [`auto`, `webp`],
          placeholder: `blurred`,
          quality: 80,
          breakpoints: [750, 1080, 1366, 1920],
        },
        stripMetadata: false,
        useMozJpeg: true,
        failOn: `error`,
      },
    },
  ],
}

```

## Transform Options for Fine-Grained Image Processing

When querying images with `gatsbyImageData`, you can pass transform options that override your global defaults. The `healOptions` function in [`plugin-options.ts`](https://github.com/gatsbyjs/gatsby/blob/main/plugin-options.ts) normalizes these arguments before passing them to [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts) for execution.

### Dimension and Layout Control

- **`width`** and **`height`**: Target dimensions in pixels. If neither is provided, defaults to `400`.
- **`fit`**: Resize strategy accepting `cover` (default), `contain`, `fill`, `inside`, or `outside`. Controls how the image fills the target dimensions.
- **`cropFocus`**: Focus point for cropping when using `cover` or `contain` fits. Options include `center`, `north`, `entropy`, and `sharp.strategy.attention` (default).
- **`background`**: Background color when the image does not fully fill the output canvas, accepting values like `'rgba(0,0,0,1)'` or hex codes. Critical for `contain` and `outside` fits.

### Quality and Compression

- **`quality`**: General image quality (0–100), defaulting to the plugin's `defaultQuality` setting.
- **`jpegQuality`**, **`pngQuality`**, **`webpQuality`**: Override the general quality for specific formats.
- **`jpegProgressive`**: Creates progressive JPEGs when `true` (default), enabling progressive download.
- **`pngCompressionLevel`**: PNG compression level from 0–9 (default `9` for maximum compression).
- **`pngCompressionSpeed`**: Trade-off between speed and quality for PNG, ranging 1–10 (default `4`).

### Format Conversion

- **`toFormat`**: Force output format to `jpg`, `png`, `webp`, `avif`, or `tiff`. If omitted, the plugin uses the source extension.
- **`toFormatBase64`**: Override the format used for base64 placeholders.
- **`base64Width`**: Width of the base64 placeholder image (default `20`).

### Visual Effects and Manipulation

- **`grayscale`**: Converts the image to 8-bit grayscale when set to `true` (handled in [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts) lines 13–16).
- **`duotone`**: Applies a duotone color map with `highlight`, `shadow`, and optional `opacity` properties (processed in [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts) lines 23–30 via [`duotone.ts`](https://github.com/gatsbyjs/gatsby/blob/main/duotone.ts)).
- **`rotate`**: Rotates the image by specified degrees after cropping (lines 18–22 in [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts)).
- **`trim`**: Trims edges that are the same color using Sharp's trim functionality (lines 62–65).

## Example GraphQL Queries with Sharp Options

**Basic responsive image with multiple formats:**

```graphql
{
  file(relativePath: { eq: "hero.jpg" }) {
    childImageSharp {
      gatsbyImageData(
        width: 1200
        placeholder: BLURRED
        formats: [AUTO, WEBP, AVIF]
      )
    }
  }
}

```

**Custom PNG compression with contained fit:**

```graphql
{
  file(relativePath: { eq: "logo.png" }) {
    childImageSharp {
      gatsbyImageData(
        width: 400
        pngOptions: { compressionSpeed: 8, quality: 70 }
        jpegOptions: { quality: 80, progressive: true }
        fit: CONTAIN
        background: "#ffffff"
      )
    }
  }
}

```

**Duotone effect with rotation:**

```graphql
{
  file(relativePath: { eq: "portrait.jpg" }) {
    childImageSharp {
      gatsbyImageData(
        width: 800
        duotone: { highlight: "#ff6a00", shadow: "#1e1e1e", opacity: 70 }
        grayscale: true
        rotate: 90
        fit: INSIDE
      )
    }
  }
}

```

## How the Image Processing Pipeline Works

The source code in `packages/gatsby-plugin-sharp/src` implements a modular pipeline that processes images during the build phase:

1. **Query Resolution**: When Gatsby encounters a `gatsbyImageData` query, `gatsby-plugin-image` builds a `transformOptions` object containing your specified arguments.

2. **Option Merging**: The `generateImageData` function in [`image-data.ts`](https://github.com/gatsbyjs/gatsby/blob/main/image-data.ts) calls `mergeDefaults` to combine query arguments with your plugin defaults from [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js).

3. **Normalization**: The `healOptions` function in [`plugin-options.ts`](https://github.com/gatsbyjs/gatsby/blob/main/plugin-options.ts) (lines 97–103) normalizes values, applies fallbacks for width/height, and validates ranges before passing options to the Sharp pipeline.

4. **Sharp Processing**: The `processFile` function in [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts) receives the transform object and executes:
   - **Resize**: Applies `fit`, `cropFocus` (mapped to Sharp's `position`), and `background` parameters.
   - **Format Encoding**: Runs format-specific operations (`jpeg`, `png`, `webp`, `avif`) with quality and compression flags.
   - **Effects**: Conditionally applies `grayscale`, `rotate`, `duotone`, and `trim` transformations.

5. **Output Generation**: The processed buffer is written to the public directory, and metadata is cached via [`image-data.ts`](https://github.com/gatsbyjs/gatsby/blob/main/image-data.ts) to return URLs, srcSets, and placeholders to the GraphQL layer.

## Key Source Files and Implementation Details

Understanding these specific files in the gatsbyjs/gatsby repository helps you debug and extend image processing behavior:

- **[`plugin-options.ts`](https://github.com/gatsbyjs/gatsby/blob/main/plugin-options.ts)**: Contains default values, the `healOptions` merging logic, and option validation.
- **[`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts)**: Implements the actual Sharp pipeline including resize operations, format-specific encoders, and color effects.
- **[`image-data.ts`](https://github.com/gatsbyjs/gatsby/blob/main/image-data.ts)**: Builds `gatsbyImageData` objects, handles metadata extraction, and manages the default `fit` and `cropFocus` logic.
- **[`README.md`](https://github.com/gatsbyjs/gatsby/blob/main/README.md)**: Documents the public API and available configuration options.

## Summary

- Configure global defaults in [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) using the `defaults` object to establish site-wide image standards for formats, quality, and breakpoints.
- Override per-image settings via GraphQL arguments such as `quality`, `fit`, `pngOptions`, and `duotone` to handle specific use cases.
- The `healOptions` function in [`plugin-options.ts`](https://github.com/gatsbyjs/gatsby/blob/main/plugin-options.ts) merges query arguments with plugin defaults before processing begins.
- Sharp operations execute in [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts), handling resize strategies, format conversion, and visual effects like grayscale and rotation.
- Enable `useMozJpeg: true` for superior JPEG compression and set `stripMetadata: false` only when you need to preserve EXIF data for photography portfolios.

## Frequently Asked Questions

### What is the difference between `gatsby-plugin-sharp` and `gatsby-plugin-image`?

`gatsby-plugin-sharp` is the low-level image processing engine that wraps the Sharp library, handling resize, format conversion, and compression at build time. `gatsby-plugin-image` is the high-level presentation layer that provides React components like `<GatsbyImage>` and `<StaticImage>` to display those optimized images with lazy loading and layout stability. You need both plugins installed, with `gatsby-plugin-sharp` performing the heavy lifting in [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts) while `gatsby-plugin-image` consumes the generated data.

### How do I enable AVIF format support in Gatsby?

Include `AVIF` in the `formats` array within your plugin defaults or individual GraphQL queries. According to the source code in [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts), the plugin supports `avif` as a valid `toFormat` option alongside `jpg`, `png`, `webp`, and `tiff`. Note that AVIF encoding is computationally intensive and may increase build times significantly compared to WebP or JPEG generation.

### Why is my image quality poor even when I set a high quality value?

Check your `defaultQuality` setting in [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js), which defaults to `50` and may override your query expectations if not configured properly. Additionally, ensure you are not using `pngCompressionSpeed` values above `5` with low quality settings, as this prioritizes speed over compression efficiency. The `healOptions` function merges these values, so verify that you are not inadvertently setting format-specific quality (like `webpQuality`) lower than your general `quality` parameter.

### How can I keep EXIF metadata in my processed images?

Set `stripMetadata: false` in your `gatsby-plugin-sharp` configuration options within [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js). By default, the plugin strips all EXIF, ICC, and other metadata to reduce file sizes, as implemented in [`process-file.ts`](https://github.com/gatsbyjs/gatsby/blob/main/process-file.ts) (lines 40–44). Disabling this option preserves photography data like camera settings, GPS coordinates, and copyright information, though it increases file size.