@storyshelf/image
@storyshelf/image is StoryShelf’s image engine: it compares a baseline and a current screenshot with pixelmatch, renders the diff overlay, and downscales screenshots into thumbnails for AI insights, all on a pool of worker threads. @storyshelf/core depends on it and re-exports it as @storyshelf/core/diff, so most setups never install or import it directly.
It is a leaf package: it imports nothing else from StoryShelf, and a test keeps it that way.
Install
Section titled “Install”npm i @storyshelf/imagepnpm add @storyshelf/imageyarn add @storyshelf/image- npm package — install tarballs and version history.
- JSR package — TypeScript-first registry page.
- Public API reference — generated docs for every export; start here to learn the API. (The same reference is on JSR.)
- Source on GitHub — package directory on
main.
Engines
Section titled “Engines”The comparison is always pixelmatch; the engine is the PNG codec around it.
| Engine | Install | Notes |
|---|---|---|
pngjs (default) | built in | Pure JavaScript, runs anywhere. |
sharp | nub add sharp | Native (libvips); several times faster on big PNGs |
Pick one with createShelfApp({ images: { engine: "sharp" } }) or STORYSHELF_IMAGE_ENGINE; see Image engines for benchmarks and trade-offs.
import { diffImages, // (baseline, current, options, codec?) -> Promise<DiffResult> diffImagesAsync, // same, on the shared worker-thread pool downscalePng, // (png, maxEdge) -> Promise<Uint8Array>, on the configured engine configureImages, // ({ engine?, threads? }) apply testing.images.engine and testing.compare.threads verifyImageEngine, // load the configured engine now; rejects when it cannot load shutdownDiffPool, // stop the pool's workers DEFAULT_DIFF_OPTIONS, type DiffOptions, type DiffResult, type ImageEngine,} from "@storyshelf/image";configureImages is process-wide. The option beats STORYSHELF_IMAGE_ENGINE, and an unknown engine name throws.