Quick examples
Every recipe below runs as written. The flags are documented on the CLI page and the keys on Configuration โ this page is only the composition.
Squash one image
Output defaults to the current directory, so this rewrites nothing and drops the compressed copy where you are:
npx poops-images photo.jpg --out ./out
Squash a whole directory
Structure is preserved, so src/images/gallery/photo.jpg lands at
dist/images/gallery/photo.jpg:
npx poops-images --in src/images --out dist/images
Convert to WebP, and go lighter
npx poops-images --in src/images --out dist/images --format webp
npx poops-images --in src/images --out dist/images --format webp -q 60
Let it pick the smaller file
smart encodes both JPEG and WebP for every variant and keeps whichever came out smaller โ
which is the only honest way to answer the question, because the answer changes per image:
npx poops-images --in src/images --out dist/images --format smart
Add AVIF next to the smart pick when you want the modern format as well:
npx poops-images --in src/images --out dist/images --format smart,avif
A responsive set for a srcset
Three widths, two formats, per-format quality โ six variants per image plus the original:
npx poops-images src/images --out dist/images \
--widths 300,768,1024 \
--format webp,avif \
--quality webp:70,avif:50
The filenames come out as photo-300w.webp, photo-768w.webp, โฆ which is exactly what
Poops reads to assemble the srcset for you.
Square thumbnails, cropped from the center
Widths on the command line are proportional; a hard crop needs a config file:
{
"in": "src/images",
"out": "dist/images",
"sizes": [
{ "name": "thumb", "width": 300, "height": 300, "crop": true }
]
}
npx poops-images
A hero banner that keeps the sky
A wide, short crop anchored to the top, so the horizon survives and the ground is what goes:
{
"in": "src/images",
"out": "dist/images",
"sizes": [
{ "name": "hero", "width": 1920, "height": 600, "crop": ["center", "top"] }
]
}
The other eight anchors are in Sizes and crops.
A WordPress-shaped size set
The four sizes WordPress gives you, if that is the vocabulary already in your head:
{
"in": "src/images",
"out": "dist/static/images",
"sizes": [
{ "name": "thumbnail", "width": 150, "height": 150, "crop": true },
{ "name": "medium", "width": 300, "height": 300 },
{ "name": "medium_large", "width": 768, "height": 0 },
{ "name": "large", "width": 1024, "height": 1024 }
]
}
A blurred placeholder to load first
The LQIP trick: a 32px-wide blurred copy, small enough to inline, shown until the real
image arrives. skipOriginal keeps it from also emitting a full-size blur nobody wants:
{
"in": "src/images",
"out": "dist/images",
"sizes": [{ "name": "large", "width": 1600 }],
"preprocessors": [
{
"name": "lqip",
"operations": [{ "type": "blur", "sigma": 30 }],
"sizes": [{ "width": 32 }],
"skipOriginal": true
}
]
}
Out comes photo-large-1600w.jpg and photo-lqip-32w.jpg.
A grayscale copy for a hover effect
{
"name": "gray",
"operations": [{ "type": "grayscale" }],
"sizes": [{ "name": "card", "width": 400, "height": 300, "crop": true }],
"skipOriginal": true
}
Watermark a public gallery
input resolves relative to the config file, so the watermark travels with the config:
{
"name": "watermarked",
"operations": [
{ "type": "composite", "input": "assets/watermark.png", "gravity": "southeast" }
]
}
A one-off filter with no config file
npx poops-images --in src/images --out dist --preprocess blur:20
npx poops-images --in src/images --out dist --preprocess grayscale,blur:10
Files come out named photo-preprocessed-โฆ, because a CLI preprocessor has no name to
give them.
Work while you work
Watch mode processes only what changed, and removes the variants of a source you delete:
npx poops-images --in src/images --out dist/images --watch
Find out what it would do
--dry-run writes nothing and logs the plan. Pair it with --force when the output looks
stale and you want to know whether the cache is the reason:
npx poops-images --in src/images --out dist/images --dry-run
npx poops-images --in src/images --out dist/images --force --verbose
Tip
--verbose is worth having on any run you are debugging โ quiet is the default, so
without it a skipped file and a processed file look identical from outside.