npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vite-plugin-single-image-format

v2.3.1

Published

vite-plugin-single-image-format is a Vite/Rollup plugin that converts every raster asset in your build to a single output format – webp, png or avif. It can optionally re‑compress images that are already in the target format and automatically rewrites all

Readme

vite-plugin-single-image-format is a Vite/Rollup plugin that converts every raster asset in your build to a single output formatwebp, png or avif. It can optionally re-compress images that are already in the target format and automatically rewrites all references in HTML/CSS/JS (including JS output chunks, e.g. new URL('./img.png', import.meta.url)). It can also add or correct intrinsic width/height on <img> tags in generated HTML, and normalizes <source type> in <picture> to match the actual format of srcset entries (e.g. image/webp), removing incorrect/duplicate type attributes.

npm GitHub package version NPM Downloads

Install

# yarn
yarn add -D vite-plugin-single-image-format

# pnpm
pnpm add -D vite-plugin-single-image-format

# npm
npm i -D vite-plugin-single-image-format

Quick Start

// vite.config.ts
import { defineConfig } from 'vite';
import singleImageFormat from 'vite-plugin-single-image-format';

export default defineConfig({
  plugins: [
    singleImageFormat({
      format: 'avif',            // 'webp' | 'png' | 'avif' (default: 'webp')
      reencode: true,            // also re-compress files already in the target format
      htmlSizeMode: 'add-only',  // 'off' | 'add-only' | 'overwrite' (default: 'add-only')
      hashInName: true,          // add content-hash to filename (e.g. name-<hash>.avif)
      hashLength: 8,             // length of the hash prefix (default: 8)
      maxConcurrent: 1,          // limit parallel sharp jobs (encode + metadata). CI/OOM-friendly
      sharpConcurrency: 1,       // limit libvips threads per job (global). Further reduces peak memory
      avif: {
        quality: 60,
        speed: 5
      },
    }),
  ],
});

HTML post-processing

  • Adds or corrects intrinsic width/height on <img> (see htmlSizeMode).
  • Normalizes <source type> in <picture> based on the real extensions in srcset:
    • Replaces an incorrect type if present, or adds it if missing.
    • Works automatically; no extra options required.

Example:

<!-- before -->
<picture>
  <source type="image/png" srcset="/src/img/a.png 1x, /src/img/b.png 2x">
  <img src="/src/img/b.png" alt="">
</picture>

<!-- after -->
<picture>
  <source type="image/webp" srcset="./assets/img/a-xxxx.webp 1x, ./assets/img/b-yyyy.webp 2x">
  <img src="./assets/img/b-yyyy.webp" alt="">
</picture>

Note: If srcset entries remain in their original format (e.g. via ?imgfmt=keep or when converting is skipped), the type will reflect that format.

Options

| Field | Type | Default | Description | |:--------------:|:--------------------------------------------------------------------:|:------------:|:--------------------------------------------------------------------------| | format | 'webp' | 'png' | 'avif' | 'webp' | Output image format after build. | | reencode | boolean | false | Re-compress files already in the target format. | | htmlSizeMode | 'off' | 'add-only' | 'overwrite' | 'add-only' | Controls writing intrinsic width/height to <img> in generated HTML. | | hashInName | boolean | false | Insert content hash into file name (name-<hash>.<ext>); updates refs. Passthrough images are also hashed. Assets with ?imgfmt=keep remain unchanged. | | hashLength | number | 8 | Length of hex SHA-256 prefix used as <hash> (range: 1–64). | | maxConcurrent | number | 2 | Limits how many sharp operations run at once (encode + metadata). Use 1–2 to reduce peak memory in CI. | | sharpConcurrency | number | (unset) | Sets sharp.concurrency() (libvips thread pool) for the current process. Lower values reduce peak memory but can slow builds. | | webp | Sharp WebpOptions | see defaults | Options forwarded to sharp().webp(). | | png | Sharp PngOptions | see defaults | Options forwarded to sharp().png(). | | avif | Sharp AvifOptions | see defaults | Options forwarded to sharp().avif(). |

Memory / CI notes

Image encoding can be memory-intensive, especially when many large assets are processed in parallel.

  • Use maxConcurrent: 1 (or 2) to cap the number of simultaneous sharp() jobs.
  • Optionally set sharpConcurrency: 1 to reduce libvips internal parallelism and further lower peak memory.

Example (CI-safe):

singleImageFormat({
  format: 'webp',
  maxConcurrent: 1,
  sharpConcurrency: 1,
})

Default webp options

| Option | Default | Description | |:----------------:|:-------:|:-------------------------------| | quality | 88 | RGB quality (1-100). | | alphaQuality | 90 | Alpha channel quality (0-100). | | smartSubsample | true | Enable smart subsampling. |

Default png options

| Option | Default | Description | |:-------------------:|:-------:|:-------------------------------------------------------------------| | quality | 80 | Palette quantisation quality (1-100) – used when palette = true. | | compressionLevel | 9 | Deflate compression level (0-9). | | palette | true | Generate an 8-bit indexed palette. | | adaptiveFiltering | true | Enable adaptive filtering. |

Default avif options

| Option | Default | Description | |:----------:|:-------:|:--------------------------------------------------------| | quality | 60 | Visual quality (0-100). | | lossless | false | Produce lossless output. | | speed | 5 | CPU/bandwidth trade-off (0-10, lower is slower/better). |

Local opt-out: ?imgfmt=keep

You can prevent conversion/renaming per image by appending a query flag to its reference. The asset will pass through unchanged, but dimensions will still be collected (when possible) for HTML sizing.

<!-- stays in original format -->
<img src="/src/assets/brand.png?imgfmt=keep" alt="Brand">

Notes

  • When hashInName is enabled, assets marked with ?imgfmt=keep are left as-is (the flag is removed from references in final code).
  • Passthrough case (already in target format and reencode: false) will still receive a hashed filename and updated references when hashInName: true.
  • Works for references found in generated JS chunks as well (e.g. URLs produced via import.meta.url).

Tip: You can use the flag in imports, templates, or HTML — anywhere the path is visible to Vite’s pipeline.

Content hash in filename

When hashInName: true, output names include a content hash computed from the final bytes (after conversion), e.g.:

images/banner.jpg   → images/banner-3f9a2c1b.webp
icons/logo.webp     → icons/logo-f0c1a9b3.webp  (passthrough)
  • Hash algorithm: SHA-256 (hex), truncated to hashLength characters (default: 8).
  • All references in HTML/CSS/JS are updated accordingly.

Supported input formats

png, jpg/jpeg, webp, gif, avif, heif/heic, tiff, bmp, jp2

Note: AVIF/HEIF/JP2 require a libvips build with the respective decoders. Encoding AVIF requires libvips compiled with AVIF encoder support.

License

MIT