Fast, portable image processing for Node agents.
Rastermill provides a small image-processing API for server-side Node code. It uses
Photon for fast in-process image work and can fall back to native tools such as
sips, ImageMagick, GraphicsMagick, or ffmpeg for formats that need external
codec support.
Docs: https://rastermill.com/
import { createRastermill } from "rastermill";
const rastermill = createRastermill({
limits: {
inputPixels: 25_000_000,
outputPixels: 25_000_000,
},
});
const info = await rastermill.probe(imageBuffer);
const jpeg = await rastermill.encode(imageBuffer, {
format: "jpeg",
resize: { maxSide: 1600 },
quality: 85,
});const rastermill = createRastermill(options);The API is three methods:
probe(input)— readformat,width,height,bytes,hasAlpha, andorientationfrom the header, without a full decode.encode(input, options)— resize and re-encode to aformat("jpeg","png", or"webp"); returns the bytes plus the final dimensions.encodeWithinBytes(input, options)— encode under a byte budget, searching across dimensions, JPEG quality, and PNG compression; the result says whether the budget was met.
The same three are also exported as standalone functions backed by a lazy default-configured instance:
import { probe, encode, encodeWithinBytes } from "rastermill";A straight format conversion (e.g. HEIC/AVIF → JPEG) is just encode(input, { format: "jpeg" }) with no resize. JPEG EXIF orientation is baked in by default; HEIC orientation handling depends on the native backend. Pass autoOrient: false to skip explicit orientation work.
backend: "auto" tries Photon first for supported formats, then native tools
when a format or operation needs external codec support. You can force a backend
with backend: "photon", "sips", "imagemagick", "graphicsmagick", or
"ffmpeg".
Rastermill refuses to decode images with unknown dimensions, images larger than the configured input pixel budget, or resize targets larger than the configured output pixel budget.