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.json in 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.