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

Use gatsby-plugin-sharp to process images at build time by configuring global defaults in 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 and 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 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 (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:

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 normalizes these arguments before passing them to 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 lines 13–16).
  • duotone: Applies a duotone color map with highlight, shadow, and optional opacity properties (processed in process-file.ts lines 23–30 via duotone.ts).
  • rotate: Rotates the image by specified degrees after cropping (lines 18–22 in 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:

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

Custom PNG compression with contained fit:

{
  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:

{
  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 calls mergeDefaults to combine query arguments with your plugin defaults from gatsby-config.js.

  3. Normalization: The healOptions function in 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 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 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: Contains default values, the healOptions merging logic, and option validation.
  • process-file.ts: Implements the actual Sharp pipeline including resize operations, format-specific encoders, and color effects.
  • image-data.ts: Builds gatsbyImageData objects, handles metadata extraction, and manages the default fit and cropFocus logic.
  • README.md: Documents the public API and available configuration options.

Summary

  • Configure global defaults in 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 merges query arguments with plugin defaults before processing begins.
  • Sharp operations execute in 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 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, 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, 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. By default, the plugin strips all EXIF, ICC, and other metadata to reduce file sizes, as implemented in 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →