Next.js plugin for embedding optimized images.

  • import JPEG, PNG, WebP, and AVIF images
  • output to WebP and optional AVIF
  • resize to multiple screen sizes and densities
  • optimize WebP and fallback images using Sharp
  • preload and lazy load with modern browser hints
  • prevent layout shift with automatic width/height attributes
  • streamlined usage with the built in <Picture /> component
  • art direction with different images for different breakpoints
  • fast deployment and development workflow using persistent cache

One size per breakpoint

The sizes query describes the image's CSS width at each configured breakpoint. Next-img generates each size at the configured pixel densities, which default to 1x and 2x.

<Picture src={require('../images/coffee1.jpg?sizes=375,860&formats=avif,webp')} alt='Coffee' preload />

Output

<link
    rel="preload"
    as="image"
    type="image/avif"
    fetchPriority="high"
    imageSrcSet="/next-img/_next/static/media/generated.3orsu88w_94lw.avif 375w,
                /next-img/_next/static/media/generated.2t337k6wi961x.avif 750w,
                /next-img/_next/static/media/generated.3qkeqt1esodi1.avif 860w,
                /next-img/_next/static/media/generated.1i1r4s71n6v02.avif 1720w"
    imageSizes="(max-width: 768px) 375px, 860px"
/>
<picture>
    <source
        type="image/avif"
        srcSet="/next-img/_next/static/media/generated.3orsu88w_94lw.avif 375w,
                /next-img/_next/static/media/generated.2t337k6wi961x.avif 750w,
                /next-img/_next/static/media/generated.3qkeqt1esodi1.avif 860w,
                /next-img/_next/static/media/generated.1i1r4s71n6v02.avif 1720w"
        sizes="(max-width: 768px) 375px, 860px"
    />
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.37bi_v_ok3_y3.webp 375w,
                /next-img/_next/static/media/generated.3waxu_3z8ydow.webp 750w,
                /next-img/_next/static/media/generated.3cvfwd-4hwt0f.webp 860w,
                /next-img/_next/static/media/generated.1yv38-cru8s0_.webp 1720w"
        sizes="(max-width: 768px) 375px, 860px"
    />

    <img
        alt="Coffee"
        src="/next-img/_next/static/media/generated.3jvgkc79r3yro.jpg"
        srcSet="/next-img/_next/static/media/generated.3jvgkc79r3yro.jpg 375w,
                /next-img/_next/static/media/generated.2m-j0pudgg-k_.jpg 750w,
                /next-img/_next/static/media/generated.0e4s9-go4az7r.jpg 860w,
                /next-img/_next/static/media/generated.1es_oemak8qli.jpg 1720w"
        sizes="(max-width: 768px) 375px, 860px"
        width="375"
        height="250"
        loading="eager"
        fetchPriority="high"
    />
</picture>
Coffee

Override breakpoints

Override the configured breakpoints for one image. This example maps three CSS sizes to breakpoints at 768px and 1080px.

<Picture
  src={require('../images/coffee2.jpg?sizes=375,600,860')}
  breakpoints={[768,1080]}
  alt='Coffee'
/>

Output

<picture>
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.3p1ew7ztl644o.webp 375w,
                /next-img/_next/static/media/generated.0ykik_g38i92h.webp 750w,
                /next-img/_next/static/media/generated.2o7e5bxm4kmpe.webp 600w,
                /next-img/_next/static/media/generated.3xytan6_nta2d.webp 1200w,
                /next-img/_next/static/media/generated.3tdwweqwpaea5.webp 860w,
                /next-img/_next/static/media/generated.1xdj_7bf3dy2z.webp 1720w"
        sizes="(max-width: 768px) 375px, (max-width: 1080px) 600px, 860px"
    />

    <img
        alt="Coffee"
        src="/next-img/_next/static/media/generated.03n1xg0fqcblp.jpg"
        srcSet="/next-img/_next/static/media/generated.03n1xg0fqcblp.jpg 375w,
                /next-img/_next/static/media/generated.3a9cu66q8wpxp.jpg 750w,
                /next-img/_next/static/media/generated.0hk3h4bgohed1.jpg 600w,
                /next-img/_next/static/media/generated.2ykl2k2n0ynpn.jpg 1200w,
                /next-img/_next/static/media/generated.3uwjqfqu3-4sr.jpg 860w,
                /next-img/_next/static/media/generated.0fb5x2mqis53z.jpg 1720w"
        sizes="(max-width: 768px) 375px, (max-width: 1080px) 600px, 860px"
        width="375"
        height="250"
    />
</picture>
Coffee

Override HTML sizes attribute

Use the sizes prop to tell the browser how wide the image will render at each breakpoint.

<Picture
  src={require('../images/coffee3.jpg?sizes=375,600,860')}
  sizes='(max-width: 768px) 100vw, (max-width: 1180px) 600px, 860px'
  alt='Coffee'
/>

Output

<picture>
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.1by80jqblypkn.webp 375w,
                /next-img/_next/static/media/generated.1_u9__4w7or1v.webp 750w,
                /next-img/_next/static/media/generated.3mi3rb_v1qtfv.webp 600w,
                /next-img/_next/static/media/generated.2hsjp-d5nnigf.webp 1200w,
                /next-img/_next/static/media/generated.3x4v-hg-voy7w.webp 860w,
                /next-img/_next/static/media/generated.1yispcm-0veu-.webp 1720w"
        sizes="(max-width: 768px) 100vw, (max-width: 1180px) 600px, 860px"
    />

    <img
        alt="Coffee"
        src="/next-img/_next/static/media/generated.0c-prf8ky11pj.jpg"
        srcSet="/next-img/_next/static/media/generated.0c-prf8ky11pj.jpg 375w,
                /next-img/_next/static/media/generated.0t9y71jpo6355.jpg 750w,
                /next-img/_next/static/media/generated.1r1buooodg2g9.jpg 600w,
                /next-img/_next/static/media/generated.1w4hgc4jjcgpq.jpg 1200w,
                /next-img/_next/static/media/generated.03d-lxjcuacet.jpg 860w,
                /next-img/_next/static/media/generated.3u2zx6qvoj2a7.jpg 1720w"
        sizes="(max-width: 768px) 100vw, (max-width: 1180px) 600px, 860px"
        width="375"
        height="240"
    />
</picture>
Coffee

Single image

Without sizes, next-img keeps the source dimensions and emits one candidate per format. Large bare imports warn by default; provide CSS sizes for content images.

<Picture src={require('../images/coffee4.jpg')} alt='Coffee' />

Output

<picture>
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.2dg8vxrh9uwsg.webp 1720w"
        sizes="1720px"
    />

    <img
        alt="Coffee"
        src="/next-img/_next/static/media/generated.00txrallwtvjn.jpg"
        srcSet="/next-img/_next/static/media/generated.00txrallwtvjn.jpg 1720w"
        sizes="1720px"
        width="1720"
        height="1227"
    />
</picture>
Coffee

Art direction

Use sources to show a different crop or image at each breakpoint. Each conditional source has a media attribute; the final unconditional source is the fallback.

<Picture
  sources={[
    { src: require('../images/coffee5-s.jpg?sizes=375'), media: '(max-width: 768px)' },
    { src: require('../images/coffee5-m.jpg?sizes=600'), media: '(max-width: 1180px)' },
    { src: require('../images/coffee5-l.jpg?sizes=860') },
  ]}
  alt='Coffee'
/>

Output

<picture>
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.1f_hvgda7gj__.webp 375w,
                /next-img/_next/static/media/generated.2eei53aopsp_m.webp 750w"
        sizes="375px"
        media="(max-width: 768px)"
        width="375"
        height="563"
    />
    <source
        type="image/jpeg"
        srcSet="/next-img/_next/static/media/generated.2aqwy9a_vvyil.jpg 375w,
                /next-img/_next/static/media/generated.1dv-vi3w7c4p_.jpg 750w"
        sizes="375px"
        media="(max-width: 768px)"
        width="375"
        height="563"
    />
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.3vw6c6jyos5u5.webp 600w,
                /next-img/_next/static/media/generated.3-o642fwg0sgz.webp 1200w"
        sizes="600px"
        media="(max-width: 1180px)"
        width="600"
        height="612"
    />
    <source
        type="image/jpeg"
        srcSet="/next-img/_next/static/media/generated.33gixk2bcow3i.jpg 600w,
                /next-img/_next/static/media/generated.24zde4ibcf4-t.jpg 1200w"
        sizes="600px"
        media="(max-width: 1180px)"
        width="600"
        height="612"
    />
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.2d0s60_jjf4p2.webp 860w,
                /next-img/_next/static/media/generated.1y1ne759imohd.webp 1720w"
        sizes="860px"
        width="860"
        height="552"
    />
    <source
        type="image/jpeg"
        srcSet="/next-img/_next/static/media/generated.22g8261khc222.jpg 860w,
                /next-img/_next/static/media/generated.1udbtmxixct5t.jpg 1720w"
        sizes="860px"
        width="860"
        height="552"
    />

    <img
        alt="Coffee"
        src="/next-img/_next/static/media/generated.22g8261khc222.jpg"
        srcSet="/next-img/_next/static/media/generated.22g8261khc222.jpg 860w,
                /next-img/_next/static/media/generated.1udbtmxixct5t.jpg 1720w"
        sizes="860px"
        width="860"
        height="552"
    />
</picture>
Coffee

One file per size

Next-img normally generates every CSS size at 1x and 2x. Set densities=1x when you need only one output file for each size.

<Picture src={require('../images/coffee6.jpg?sizes=300,600,900,1200,1500&densities=1x')} sizes='100vw' alt='Coffee' />

Output

<picture>
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.2v6l6sk226oel.webp 300w,
                /next-img/_next/static/media/generated.0bdgq1oanha7g.webp 600w,
                /next-img/_next/static/media/generated.288ixu-dp5qnc.webp 900w,
                /next-img/_next/static/media/generated.0vu1qezzyamrc.webp 1200w,
                /next-img/_next/static/media/generated.3kund1uy1styz.webp 1500w"
        sizes="100vw"
    />

    <img
        alt="Coffee"
        src="/next-img/_next/static/media/generated.344cphiu0pvhh.jpg"
        srcSet="/next-img/_next/static/media/generated.344cphiu0pvhh.jpg 300w,
                /next-img/_next/static/media/generated.3o4rixhn65cpz.jpg 600w,
                /next-img/_next/static/media/generated.3eos581-00ef-.jpg 900w,
                /next-img/_next/static/media/generated.0fuhbw-zd8ynw.jpg 1200w,
                /next-img/_next/static/media/generated.3i5n87vvt094w.jpg 1500w"
        sizes="100vw"
        width="300"
        height="200"
    />
</picture>
Coffee

PNG images

PNG inputs produce lossless WebP plus a PNG fallback by default.

<Picture src={require('../images/illustration.png?sizes=480,860')} alt='Illustration' />

Output

<picture>
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.3wxp8pttzfwhi.webp 480w,
                /next-img/_next/static/media/generated.2hz49n9--8k6j.webp 960w,
                /next-img/_next/static/media/generated.1k90a825bu5ue.webp 860w,
                /next-img/_next/static/media/generated.1e4pje1ii6g2a.webp 1344w"
        sizes="(max-width: 768px) 480px, 860px"
    />

    <img
        alt="Illustration"
        src="/next-img/_next/static/media/generated.303q433ruz8q-.png"
        srcSet="/next-img/_next/static/media/generated.303q433ruz8q-.png 480w,
                /next-img/_next/static/media/generated.31m08ig5qp8fq.png 960w,
                /next-img/_next/static/media/generated.1ao_91o0pl_92.png 860w,
                /next-img/_next/static/media/generated.2n0nojul17-l6.png 1344w"
        sizes="(max-width: 768px) 480px, 860px"
        width="480"
        height="257"
    />
</picture>
Illustration

Other query params and component props

Query parameters control image processing. Other Picture props are forwarded to the underlying img. See the README for the full API.

<Picture
  src={require('../images/coffee7.jpg?sizes=375,860&jpeg[quality]=10&jpeg[webp][quality]=10')}
  className='coffee'
  data-demo='coffee'
  alt='Three cups of coffee with different amounts of milk'
  loading='lazy'
/>

Output

<picture>
    <source
        type="image/webp"
        srcSet="/next-img/_next/static/media/generated.28xg6cn06u0qx.webp 375w,
                /next-img/_next/static/media/generated.1j0i7n19p08ty.webp 750w,
                /next-img/_next/static/media/generated.1h4sg6bpe_9s_.webp 860w,
                /next-img/_next/static/media/generated.2kpv66dvy_g3j.webp 1720w"
        sizes="(max-width: 768px) 375px, 860px"
    />

    <img
        class="coffee"
        data-demo="coffee"
        alt="Three cups of coffee with different amounts of milk"
        src="/next-img/_next/static/media/generated.1--x1haj2i8cb.jpg"
        srcSet="/next-img/_next/static/media/generated.1--x1haj2i8cb.jpg 375w,
                /next-img/_next/static/media/generated.081g_snub9hx5.jpg 750w,
                /next-img/_next/static/media/generated.0in40bk69ghfe.jpg 860w,
                /next-img/_next/static/media/generated.3-9eiz2oa5_i4.jpg 1720w"
        sizes="(max-width: 768px) 375px, 860px"
        width="375"
        height="252"
        loading="lazy"
    />
</picture>
Three cups of coffee with different amounts of milk