@254guru/webp-convert
v2.4.0
Published
Automatically convert PNG/JPG images to WebP with responsive size variants. CLI, file watcher, build plugin, and programmatic API.
Maintainers
Readme
webp-convert
Automatically convert PNG/JPG/GIF/TIFF images to WebP with responsive size variants. Zero-config CLI, file watcher, build plugins (Vite / Rollup / Webpack), and programmatic API.
Install
# npm
npm install webp-convert
# yarn
yarn add webp-convert
# pnpm
pnpm add webp-convert
# global CLI
npm install -g webp-convertUses
sharp— no external binaries required (cwebp, ImageMagick, etc.).
Quick start
# Convert everything in assets/images (default)
webp-convert
# Custom dir + quality
webp-convert src/img -q 90
# Watch mode — auto-converts on file change
webp-convert src/img --watch
# Custom responsive sizes
webp-convert src/img --sizes 1200,800,400
# Write outputs to a separate directory
webp-convert src/img -o dist/imgCLI reference
Usage: webp-convert [input-dir] [options]
Options:
-o, --output <dir> Output directory (default: same as source)
-q, --quality <0-100> WebP quality (default: 80)
--lossless Lossless encoding
--sizes <w,w,...> Responsive widths, e.g. 1200,800,400 (0 = full-size)
--no-full Skip full-size output (only responsive sizes)
--recursive, -r Recurse into subdirectories
--no-overwrite Skip files that already have a .webp counterpart
--watch, -w Watch mode
--config <file> Load config from a JS/JSON file
--silent Suppress all output
-h, --help Show helpConfig file
Create webp.config.js in your project root:
// webp.config.js
module.exports = {
input: 'src/images',
output: 'public/images', // omit to write next to originals
quality: 85,
lossless: false,
recursive: true,
overwrite: true,
sizes: [
{ width: 0, suffix: '' }, // full size
{ width: 1200, suffix: '-1200' },
{ width: 800, suffix: '-800' },
{ width: 400, suffix: '-400' },
],
extensions: ['.png', '.jpg', '.jpeg', '.gif', '.tiff'],
};Then run:
webp-convert --config webp.config.jsProgrammatic API
const { convert, watch, convertFile } = require('webp-convert');
// Convert a whole directory
await convert({
input: 'src/images',
quality: 85,
sizes: [
{ width: 0, suffix: '' },
{ width: 800, suffix: '-800' },
],
onFile: ({ src, dest, size }) => {
console.log(`${src} → ${dest} (${size} bytes)`);
},
});
// Convert a single file
await convertFile('src/hero.png', { quality: 90 });
// Watch a directory
const watcher = watch({ input: 'src/images', recursive: true });
// stop later:
watcher.close();Vite plugin
// vite.config.js
import { defineConfig } from 'vite';
import { vitePlugin } from 'webp-convert';
export default defineConfig({
plugins: [
vitePlugin({
input: 'public/images',
quality: 85,
sizes: [
{ width: 0, suffix: '' },
{ width: 800, suffix: '-800' },
{ width: 400, suffix: '-400' },
],
}),
],
});Runs on vite build and watches during vite dev.
Rollup plugin
// rollup.config.js
import { rollupPlugin } from 'webp-convert';
export default {
plugins: [
rollupPlugin({ input: 'src/images' }),
],
};Webpack plugin
// webpack.config.js
const { WebpackWebpPlugin } = require('webp-convert');
module.exports = {
plugins: [
new WebpackWebpPlugin({ input: 'src/images', quality: 80 }),
],
};Output structure
Given hero.jpg in src/images/:
src/images/
├── hero.jpg (original, kept by default)
├── hero.webp (full size)
├── hero-800.webp (800px wide, aspect-ratio preserved)
└── hero-400.webp (400px wide)HTML usage
<picture>
<source
type="image/webp"
srcset="hero-400.webp 400w, hero-800.webp 800w, hero.webp 1600w"
sizes="(max-width: 400px) 400px, (max-width: 800px) 800px, 1600px"
/>
<img src="hero.jpg" alt="Hero image" />
</picture>License
MIT
