Bun.Image constructor input types
Bun.Image accepts file paths (filesystem paths as strings), bytes (Buffer, ArrayBuffer, or TypedArray), or Blob objects including Bun.file() and Bun.s3.file(). Blob#image() is shorthand for new Bun.Image(blob). Format is sniffed from bytes; extensions and Content-Type are ignored.
Bun.Image security warning for path strings
Path strings are filesystem paths. Do not pass user-controlled strings directly to the Bun.Image constructor as this creates an arbitrary-file-read vulnerability. Instead, read untrusted input into a Buffer using fetch or Bun.file with your own validation, then pass the bytes.
Bun.Image constructor second options argument
The Bun.Image constructor accepts a second options object with: maxPixels (reject if width*height exceeds this value, checked after reading header before allocating pixel buffer, default matches Sharp at ~268 MP), and autoOrient (apply JPEG EXIF Orientation before other operations, default: true).
Bun.Image buffer mutation restriction
When passing TypedArray or ArrayBuffer to Bun.Image, do not mutate it while a terminal is pending, as decode runs off-thread and borrows the bytes. SharedArrayBuffer and resizable buffers are refused; use buf.slice() to pass a fixed view.
Bun.Image metadata method
Call await img.metadata() to read width, height, and format without decoding pixel data. Returns an object with properties: width (number), height (number), format (string indicating the image format like 'jpeg').
Bun.Image resize method signatures and options
img.resize() supports multiple forms: resize(800) sets width to 800 and keeps aspect ratio; resize(800, 600) stretches to exactly 800×600; resize(800, 600, options) accepts fit and other options. Options include: fit ("fill" default stretches to exact dimensions, "inside" preserves aspect ratio and fits within the box), withoutEnlargement (boolean, never upscale), and filter (resampling kernel).
Bun.Image resize filter options
The filter option in resize() selects the resampling kernel. Available filters: "lanczos3" (default, general-purpose, sharpest for photos), "lanczos2" (slightly softer, fewer ringing artifacts), "mitchell" (smooth gradients, classic bicubic compromise), "cubic" (Catmull-Rom, sharper than Mitchell, can ring), "mks2013" / "mks2021" (Magic Kernel Sharp used by Facebook/Instagram), "bilinear" / "linear" (fast, soft), "box" (area-average, good for large integer downscales), "nearest" (pixel art, hard edges).
Bun.Image JPEG decode optimization for thumbnails
When the source is a JPEG and the target is at most half the source size, decode skips straight to the nearest M/8 IDCT scale. This means generating a thumbnail from a 24 MP photo never materializes the full-resolution buffer.
Bun.Image rotate and flip methods
img.rotate(degrees) rotates 90° clockwise; only multiples of 90 are supported. img.flip() mirrors vertically about the x-axis. img.flop() mirrors horizontally about the y-axis.
Bun.Image modulate method
img.modulate(options) adjusts image properties. Options: brightness (number, 1 = unchanged), saturation (number, 0 = greyscale, 1 = unchanged, >1 = boost).
Bun.Image output format methods
Format methods set the encode target; without one, source format is reused. Methods: jpeg({ quality: 1-100, default 80 }), png({ compressionLevel: 0-9, default 6, palette: boolean, colors: number, dither: boolean }), webp({ quality: number, lossless: boolean }), heic({ quality: number }), avif({ quality: number }). palette: true quantizes to ≤256-color palette with indexed PNG (color-type 3), optionally with Floyd–Steinberg dither, typically 3–5× smaller than truecolor for screenshots and UI assets.
Bun.Image terminal methods
Terminal methods trigger pipeline execution: await img.bytes() returns Uint8Array, await img.buffer() returns Buffer, await img.blob() returns Blob with MIME type set, await img.toBase64() returns string, await img.dataurl() returns "data:image/png;base64,..." URL, await img.write(destination) returns number of bytes written. write() accepts path string, Bun.file(), Bun.s3.file(), or fd. If no format method was chained and destination is a path string, the extension (.jpg/.png/.webp/.heic/.avif) picks the format.
Bun.Image placeholder method for LQIP
img.placeholder() returns a low-quality placeholder as a ThumbHash-rendered ≤32px blur data: URL (typically 400–700 bytes). No client-side decoder is needed, suitable for inlining in HTML before the real image loads.
Bun.Image progressive JPEG encoding
Call img.jpeg({ progressive: true }) to encode a progressive JPEG for coarse-to-fine rendering of the image itself.
Bun.Image output dimensions after terminal
After the first terminal method resolves, img.width and img.height reflect the output dimensions. Before a terminal is awaited, they are -1.
Bun.Image as Bun.serve response body
A Bun.Image pipeline is a valid Response body and automatically sets Content-Type. To keep encode off the JS thread in a server handler, await a terminal method first to get a blob, buffer, or bytes, then pass to Response. Passing the pipeline directly (new Response(img)) also works but runs the encode synchronously during body init.
Bun.Image.fromClipboard method
Bun.Image.fromClipboard() reads PNG, TIFF, HEIC, JPEG, WebP, GIF, or BMP from the system pasteboard. On macOS and Windows it reads from the clipboard; on Linux it always returns null (call wl-paste/xclip yourself and pass bytes to constructor). Returns null if there's no image in clipboard.
Bun.Image clipboard monitoring methods
Use clipboardChangeCount() to poll a single integer read, and call hasClipboardImage() only when the count changes. This is the documented pattern for passive "image in clipboard, press ⌘V" hints since macOS has no clipboard-change notification.
Bun.Image platform backend support table
Platform support: JPEG/PNG/WebP available on Linux (libjpeg-turbo, spng, libwebp), macOS (same), Windows (same). BMP/GIF decode: Linux (built-in), macOS (ImageIO), Windows (WIC). TIFF decode: Linux (not supported), macOS (ImageIO), Windows (WIC). Resize/rotate/flip: Linux (Highway SIMD), macOS (Accelerate vImage), Windows (Highway SIMD). HEIC/AVIF: Linux (not supported, ERR_IMAGE_FORMAT_UNSUPPORTED), macOS (ImageIO, AVIF encode needs OS AV1 encoder on Apple Silicon M3+ only, Intel Mac and M1/M2 reject), Windows (WIC, requires HEIF Image Extensions/AV1 Video Extension from Microsoft Store). Clipboard: Linux (returns null), macOS (NSPasteboard), Windows (Win32). AVIF decode works macOS 13+ with ImageIO.
Bun.Image ERR_IMAGE_FORMAT_UNSUPPORTED error handling
When a system-backend format is unavailable on the current machine, the terminal rejects with error.code === "ERR_IMAGE_FORMAT_UNSUPPORTED". Branch on this error to fall back to a portable format like WebP.
Bun.Image backend selection for consistency
JPEG, PNG, and WebP use the same statically-linked codecs on every platform, so encoded output is byte-identical across Linux, macOS, and Windows. Set Bun.Image.backend = "bun" to force the portable Highway path for geometry operations (default is "system" on macOS/Windows). This is useful for golden-image tests.
Bun.Image pipeline chainable and lazy evaluation
Bun.Image is shaped after Sharp: construct from an input, chain transforms, pick an output format, then await a terminal method. Nothing runs until a terminal is awaited, and the work executes off the JavaScript thread.
Bun.Image built-in codecs and no dependencies
Bun.Image is built on libjpeg-turbo, spng, libwebp, and SIMD geometry kernels, with zero npm dependencies and no native addon build step.
Bun.Image supported formats
Bun.Image supports decoding and encoding JPEG, PNG, WebP, HEIC, and AVIF. Additional decode formats on specific platforms: BMP, GIF, TIFF (platform-specific).
Bun.Image example usage
Example: await Bun.file("photo.jpg").image().resize(400, 400, { fit: "inside" }).webp({ quality: 80 }).write("thumb.webp"); This loads photo.jpg, resizes to fit within 400×400 while preserving aspect ratio, encodes as WebP at quality 80, and writes to thumb.webp.