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-sharp

v1.6.3

Published

A Vite plugin for image compression using sharp and svgo

Readme

vite-plugin-sharp

npm version license npm downloads

中文 | English


中文

基于 sharp(光栅图片)和 svgo(SVG)的 零配置 Vite 图片压缩插件。构建时自动压缩 bundle 产物及 public 目录中的所有图片,无需额外设置。

为什么选 vite-plugin-sharp?

  • 性能:底层使用 libvips(C++ 原生绑定),比 imagemin 快 4–5 倍
  • 全覆盖:同时处理 JS/CSS 引入的 bundle 资源 public/ 静态目录
  • 智能缓存:基于文件内容 hash,未修改的文件零开销跳过
  • 安全:压缩后体积更大时保留原图,永不劣化产物
  • 透明:终端逐文件展示压缩前后体积,与 Vite 输出风格一致

功能概览

| 能力 | 说明 | |------|------| | 格式支持 | jpeg / jpg / png / gif / tiff / webp / avif(sharp)+ svg(svgo) | | 处理范围 | bundle 内联资源 + public 静态目录 | | 缓存 | 文件内容 hash,可自定义路径或禁用 | | 过滤 | include / exclude 白黑名单 | | 限流 | concurrency 并发控制、minSize / minRatio 阈值 | | 缩放 | resize 限制最大宽高,不放大小图 | | 兼容性 | Vite 4 / 5 / 6 / 7 / 8+,仅 build 阶段生效 |

安装

npm install vite-plugin-sharp -D

快速开始

// vite.config.ts
import { defineConfig } from "vite";
import viteSharp from "vite-plugin-sharp";

export default defineConfig({
  plugins: [viteSharp()],
});

Tip:若使用 vite.config.js(CommonJS),建议重命名为 vite.config.mjs 以确保 ESM 依赖正常加载。

配置项

viteSharp(options?: Partial<OptionsType>)

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | filter | RegExp | /\.(jpe?g\|png\|gif\|tiff\|webp\|svg\|avif)$/i | 匹配需要处理的文件路径 | | include | RegExp \| string \| string[] | — | 白名单(优先于 filter + exclude) | | exclude | RegExp \| string \| string[] | — | 黑名单 | | cache | string \| false | node_modules/.vite/sharp-cache.json | 缓存路径,false 禁用 | | minRatio | number | 0 | 最小压缩率(0–1),低于此值保留原图 | | minSize | number | 0 | 最小文件大小(字节),小于此值跳过 | | concurrency | number | os.cpus().length | 最大并发压缩数 | | resize | ResizeConfig | — | 压缩前缩放(withoutEnlargement: true) | | compress | CompressType | 见下方 | 各格式压缩参数 |

| 格式 | 默认配置 | |------|----------| | jpeg / jpg | quality: 75chromaSubsampling: "4:4:4" | | png | quality: 75compressionLevel: 6palette: true | | webp | quality: 75effort: 4 | | avif | lossless: true | | tiff | quality: 75 | | gif | sharp 默认参数 | | svg | svgo preset-defaultmultipass: true |

完整参数参考:sharp output API · svgo 配置

使用示例

viteSharp({
  compress: {
    jpeg: { quality: 85 },
    png: { quality: 80, compressionLevel: 9 },
    webp: { quality: 80, lossless: false },
  },
});
// 只处理指定目录
viteSharp({ include: /^assets\/images\// });

// 排除特定文件
viteSharp({ exclude: ["logo.svg", "favicon.ico"] });
// 禁用缓存
viteSharp({ cache: false });

// 自定义路径(CI 中可提交复用)
viteSharp({ cache: ".cache/sharp.json" });
viteSharp({
  minRatio: 0.05,       // 节省 < 5% 则保留原图
  minSize: 10240,       // 跳过小于 10 KB 的文件
  resize: { width: 1920, height: 1080 },
  concurrency: 4,
});

终端输出

构建完成后,插件以树形结构输出每个文件的压缩结果:

[vite-plugin-sharp] compressing images...
├── dist/assets/hero-CLDdwZDr.png    13.06 kB →  12.04 kB │   -1.02 kB  (7.8%)
├── dist/assets/code-50bb2e8d.jpg    14.87 kB →   3.23 kB │  -11.65 kB (78.3%) [cached]
├── dist/images/banner.png          797.04 kB → 255.81 kB │ -541.24 kB (67.9%) [cached]
└── dist/favicon.svg                  9.52 kB →   9.52 kB │ [skipped]           [cached]

✓ 3 files compressed  -553.14 kB (65.5%)  1 skipped

| 标识 | 含义 | |------|------| | (无标识) | 本次新鲜压缩 | | [cached] | 缓存命中,跳过重压缩,直接复用上次结果 | | [skipped] | 压缩后体积更大,保留原图 |

缓存机制

| 场景 | 行为 | |------|------| | 首次构建 | 压缩所有匹配图片 | | 图片未修改 | 缓存命中,[cached],构建更快 | | 图片修改 | 仅重新压缩该文件 | | cache: false | 每次都重新压缩 |

默认缓存文件位于 node_modules/.vite/ 内,随 .gitignore 自动忽略。CI 场景可指定自定义路径持久化。

工作原理

Vite Build Pipeline
────────────────────────────────────────────────────────────────
1. generateBundle (enforce: "post")
   → 处理 bundle 中的图片(JS/CSS import),内存中压缩
   → Vite 写入磁盘时即为压缩版本

2. closeBundle
   → 扫描 dist 目录,处理 public/ 复制过来的图片
   → 磁盘上原地压缩替换
   → 通过 processedBundleKeys 去重,不会重复处理
────────────────────────────────────────────────────────────────

开发

npm run build        # 构建插件
npm run dev          # 监听模式
npm test             # 运行测试
npm run test:watch   # 监听测试

使用 webpack?

本插件仅适用于 Vite。如果你的项目使用 webpack,推荐以 sharp 作为后端的等价方案:

  • image-minimizer-webpack-plugin + imagemin-sharp(或直接用 sharp minimizer)— webpack 生态的标准图片压缩插件,支持 sharp 作为处理引擎,功能上与本插件等价。

许可证

ISC


English

Zero-config Vite image compression plugin powered by sharp (raster) and svgo (SVG). Automatically compresses all images in both the bundle output and the public directory during build.

Why vite-plugin-sharp?

  • Performance: libvips native bindings — 4–5× faster than imagemin
  • Full coverage: processes JS/CSS bundle assets and public/ static files
  • Smart caching: content-hash based, zero overhead for unchanged files
  • Safe: never replaces originals when compression yields a larger file
  • Transparent: per-file terminal output aligned with Vite's own style

Feature Overview

| Capability | Details | |------------|---------| | Formats | jpeg / jpg / png / gif / tiff / webp / avif (sharp) + svg (svgo) | | Scope | Bundle inline assets + public static directory | | Caching | Content hash, customizable path or disable | | Filtering | include / exclude allow/deny lists | | Throttling | concurrency limiter, minSize / minRatio thresholds | | Resizing | resize — max dimensions with withoutEnlargement | | Compatibility | Vite 4 / 5 / 6 / 7 / 8+, build-only |

Installation

npm install vite-plugin-sharp -D

Quick Start

// vite.config.ts
import { defineConfig } from "vite";
import viteSharp from "vite-plugin-sharp";

export default defineConfig({
  plugins: [viteSharp()],
});

Tip: If you use vite.config.js (CommonJS), rename it to vite.config.mjs to ensure ESM dependencies load correctly.

Options

viteSharp(options?: Partial<OptionsType>)

| Option | Type | Default | Description | |--------|------|---------|-------------| | filter | RegExp | /\.(jpe?g\|png\|gif\|tiff\|webp\|svg\|avif)$/i | Regex matching file paths to process | | include | RegExp \| string \| string[] | — | Allowlist (overrides filter + exclude) | | exclude | RegExp \| string \| string[] | — | Denylist | | cache | string \| false | node_modules/.vite/sharp-cache.json | Cache path, or false to disable | | minRatio | number | 0 | Min savings ratio (0–1) to replace original | | minSize | number | 0 | Min file size in bytes to process | | concurrency | number | os.cpus().length | Max parallel compressions | | resize | ResizeConfig | — | Pre-compress resize (withoutEnlargement: true) | | compress | CompressType | See below | Per-format compression options |

| Format | Defaults | |--------|----------| | jpeg / jpg | quality: 75, chromaSubsampling: "4:4:4" | | png | quality: 75, compressionLevel: 6, palette: true | | webp | quality: 75, effort: 4 | | avif | lossless: true | | tiff | quality: 75 | | gif | sharp defaults | | svg | svgo preset-default, multipass: true |

Full reference: sharp output API · svgo config

Examples

viteSharp({
  compress: {
    jpeg: { quality: 85 },
    png: { quality: 80, compressionLevel: 9 },
    webp: { quality: 80, lossless: false },
  },
});
// Process only specific directory
viteSharp({ include: /^assets\/images\// });

// Exclude specific files
viteSharp({ exclude: ["logo.svg", "favicon.ico"] });
// Disable caching
viteSharp({ cache: false });

// Custom path (sharable in CI)
viteSharp({ cache: ".cache/sharp.json" });
viteSharp({
  minRatio: 0.05,       // skip if savings < 5%
  minSize: 10240,       // skip files < 10 KB
  resize: { width: 1920, height: 1080 },
  concurrency: 4,
});

Terminal Output

After the build completes, the plugin prints compression results in a tree format:

[vite-plugin-sharp] compressing images...
├── dist/assets/hero-CLDdwZDr.png    13.06 kB →  12.04 kB │   -1.02 kB  (7.8%)
├── dist/assets/code-50bb2e8d.jpg    14.87 kB →   3.23 kB │  -11.65 kB (78.3%) [cached]
├── dist/images/banner.png          797.04 kB → 255.81 kB │ -541.24 kB (67.9%) [cached]
└── dist/favicon.svg                  9.52 kB →   9.52 kB │ [skipped]           [cached]

✓ 3 files compressed  -553.14 kB (65.5%)  1 skipped

| Indicator | Meaning | |-----------|---------| | (none) | Freshly compressed this build | | [cached] | Result replayed from cache — no recompression needed | | [skipped] | Compressed output was larger — original retained |

Caching

| Scenario | Behavior | |----------|----------| | First build | Compresses all matching images | | File unchanged | Cache hit — [cached], faster build | | File modified | Only the changed file is recompressed | | cache: false | Recompresses every file every build |

The default cache file lives inside node_modules/.vite/ and is automatically git-ignored. For CI, specify a custom path to persist across builds.

How It Works

Vite Build Pipeline
────────────────────────────────────────────────────────────────
1. generateBundle (enforce: "post")
   → Compresses bundle images (JS/CSS imports) in memory
   → Vite writes the compressed version to disk

2. closeBundle
   → Scans dist for images not handled in step 1
   → Compresses public/ files in-place on disk
   → Deduplicates via processedBundleKeys — no double processing
────────────────────────────────────────────────────────────────

Development

npm run build        # Build the plugin
npm run dev          # Watch mode
npm test             # Run tests
npm run test:watch   # Watch tests

Using webpack?

This plugin is Vite-only. For webpack projects, the recommended equivalent with sharp as the backend is:

  • image-minimizer-webpack-plugin — the standard webpack image compression plugin that supports sharp as the processing engine, functionally equivalent to this plugin.

License

ISC