Skip to content

Repository files navigation

next-img

Build-time image optimization for Next.js.

next-img resizes and compresses imported images with Sharp during the build. It emits static files, so it works with static export and does not need an image CDN or runtime optimizer.

  • Webpack and Turbopack support
  • responsive JPEG, PNG, WebP, and AVIF output
  • persistent local cache that can be committed to Git
  • automatic dimensions and EXIF orientation
  • responsive preloads and art direction through <Picture>
  • TypeScript declarations

Install

npm install next-img

Add the plugin to next.config.js:

const withImg = require('next-img/plugin')

module.exports = withImg({})

Import an image and render it:

import { Picture } from 'next-img'
import hero from './hero.jpg?sizes=375,800&formats=avif,webp'

export default function Hero() {
  return <Picture src={hero} alt='Our team at work' />
}

The image is displayed at 375px on small screens and 800px on larger screens. Next-img generates each size at 1x and 2x pixel density, in AVIF, WebP, and JPEG. The browser downloads the best candidate.

Image imports

Use query parameters to control each image:

  • sizes=375,800 describes the image's CSS width at each breakpoint.
  • densities=1x,2x controls which pixel densities to generate for every size. These are the defaults.
  • formats=avif,webp sets preferred formats. The original format remains the default fallback.
  • fallbackFormat=jpeg selects a different fallback.
  • jpeg, png, webp, and avif accept Sharp output options, for example ?jpeg[quality]=70.

Unknown options warn; malformed options fail the build. Set nextImg.strict: true to turn warnings into errors.

A bare import keeps its intrinsic dimensions:

import logo from './logo.png'

By default, next-img warns when a bare import is wider or taller than 2048px. Change maxBareImportSize, or set it to false to disable the warning.

Picture

Picture forwards standard image props and its ref to the underlying <img>. It adds width and height, generates srcset and the HTML sizes attribute, and emits <source> elements for preferred formats.

Preload an above-the-fold image with responsive metadata:

<Picture src={hero} alt='Our team at work' preload />

preload defaults to eager loading and fetchPriority="high". It preloads only the first preferred format to avoid duplicate downloads.

For art direction, provide explicit sources and finish with an unconditional fallback:

<Picture
  sources={[
    { src: mobile, media: '(max-width: 767px)', sizes: '100vw' },
    { src: desktop, sizes: '1200px' },
  ]}
  alt='Our team at work'
/>

sources is the complete ordered list. Every item except the last must have media; the final item is the fallback. Put any sizes override on the relevant source.

Automatic art-direction preloading supports one conditional source plus its fallback. Manage preloads separately for more complex source sets.

Useful component props:

  • sizes: overrides the generated HTML sizes attribute for src
  • breakpoints: overrides the configured breakpoints for src
  • preload: emits a responsive image preload
  • pictureProps: props for the outer <picture> element

Legacy image arrays remain supported through src={[mobile, desktop]} with breakpoints.

Cache and builds

Optimized files are stored in resources by default. Commit this directory or preserve it in CI. Ordinary development and production builds process missing images.

Run the CLI after changing imports or image settings. It generates missing images, repairs invalid files, and removes unused files without re-encoding healthy cache hits:

npx next-img

The cleanup build uses Turbopack. Use Webpack when your application builds with Webpack:

npx next-img --webpack

Cache modes:

  • read-write builds missing images and updates the cache. This is the default.
  • read-only fails when an optimized image is missing.
  • off stores the cache under .next instead of resources.
module.exports = withImg({
  nextImg: {
    cache: {
      mode: 'read-write',
      dir: 'resources',
    },
  },
})

Cache filenames remain stable across next-img and Sharp upgrades. Run npx next-img --force when you want to rebuild every active derivative in place. Both commands remove unused files.

The maintenance command requires a persistent cache. With cache.mode: 'off', clear .next after upgrading next-img or Sharp instead.

The deprecated persistentCache and persistentCacheDir options remain supported.

Configuration

Common plugin options:

Option Default Purpose
breakpoints [768] Breakpoints that map imported sizes to the layout
densities ['1x', '2x'] Pixel densities generated for each imported size
formats ['webp'] Preferred output formats
fallbackFormat 'original' Fallback output format
strict false Turn warnings into build errors
maxBareImportSize 2048 Warn above this intrinsic width or height; false disables it
cache { mode: 'read-write', dir: 'resources' } Cache behavior and location

JPEG, PNG, WebP, and AVIF settings accept Sharp output options.

Webpack also supports imagesDir, imagesName, imagesPublicPath, and imagesOutputPath. Turbopack controls final emitted filenames. Both bundlers honor the Next.js assetPrefix and basePath.

Set nextImg.projectDir when Next.js is invoked for an application outside the current working directory. The next-img CLI sets it automatically.

Development

npm install
npm test
npm run test:integration

The example site is available at humaans.github.io/next-img.

Publishing

Run Prepare npm release in GitHub Actions on master and choose patch, minor, or major. The workflow opens a PR that updates package.json and package-lock.json. Review it and merge it. The merge runs the tests, then stages that version on npm. The package is not public yet.

An npm maintainer, such as Karolis, reviews the tarball in the Staged Packages tab on npmjs.com and approves it with 2FA. The maintainer can also use npm stage list next-img, npm stage view <stage-id>, and npm stage approve <stage-id>. Approval makes the staged version public.

Before the first release through this workflow, configure next-img on npmjs.com:

  1. In package settings, add a trusted publisher for GitHub Actions with organization humaans, repository next-img, and workflow filename publish.yml. Allow only npm stage publish, not direct npm publish.
  2. Set Publishing access to Require two-factor authentication and disallow tokens. Ensure the person who will approve staged releases has npm publish access and 2FA enabled.

The workflow uses short-lived OIDC credentials and needs no npm write token. npm adds provenance for this public package. Keep GitHub Actions' Allow GitHub Actions to create and approve pull requests setting enabled so the preparation workflow can open its PR.

About

A Next.js plugin for embedding optimized images.

Topics

Resources

Stars

277 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages