Introduction
poops-images prepares images for the web. Point it at a directory, get back
compressed, resized, cropped and converted variants under names a srcset can be built
from. It leans on sharp for raster work and
SVGO for vectors, and keeps a cache so the second run does
almost nothing.
Why
Built because I hate opening Pixelmator Pro and ImageOptim both. I want to convert the format and optimise the image in one go, regardless of the source format. Also sometimes JPEG is lighter than WebP โ and then I have to inspect it to decide which one I'll keep, and so on.
And let me ask you this: what happens when you have to create a srcset? Make the image
responsive? You are responsible, right? Right?
Install
npm install poops-images
Node โฅ 20.9. sharp is the one dependency with a native binary; if the install fails, that
is almost always what failed.
What it does
- Compresses, generates size variants and crops
- WordPress-like notation for resizing and cropping, with a 9-position anchor grid
- Smart format selection โ compares JPEG vs WebP, keeps whichever is smaller
- Transparency detection โ auto-converts opaque PNGs and static GIFs to JPEG
- Never upscales โ skips oversized plain sizes, scales oversized crops down to fit instead
- Preprocessors โ blur, grayscale, watermark, halftone or a custom handler applied before the variants are generated
- Watch mode with incremental processing, and configurable concurrency
- A cache that tracks source dimensions, output dimensions and generated variants, plus the EXIF metadata it read on the way
Supported input formats
| Input | What comes out |
|---|---|
| JPEG, PNG, WebP | Resized, cropped and converted like anything else |
| HEIC / HEIF | JPEG when opaque, PNG when transparent |
| TIFF | JPEG when opaque, PNG when transparent |
| SVG | Minified with SVGO, no crops โ see SVG minification |
| GIF (static) | JPEG when opaque, PNG when transparent; resized and cropped like other raster images |
| GIF (animated) | Copied as-is. No compression, no crops โ the raster pipeline would drop the frames |
Where to next
Quick examples is the fastest way in: a recipe per job, each one runnable as written. Past that, two ways to drive it, and they are the same tool:
- No config file โ pass flags and go. Every flag is on the CLI page.
- Repeatable setup โ a
poops-images.jsonin the project root. Every key is on the Configuration page.
If you are here because of Poops, the part you want is
Poops integration โ the naming convention is what makes
discoverImageVariants() work.