Bun.Image for Blazing Fast, Zero-Install Image Processing

Search for a command to run...

What will be the image size?
Bun, the hyper-fast JavaScript runtime known for its incredible speed and Zig-based architecture, is being completely rewritten in Rust. For a project that has over 22 million monthly downloads and ea

Next.js 16.3 is almost here, and it's packed with a ton of improvements and let's see them in this post 1.Instant Navigation For a while now, there’s been a valid, lingering debateServer Components vs

It’s official. React has merged its long-awaited Rust port of the React Compiler (formerly known as React Forget) into the main repository. What started as an experimental research project by Joseph S

If you follow modern technology trends, you have likely been led to believe that artificial intelligence is entirely built on Python. Every tutorial, machine learning framework documentation, and open

Just when the JavaScript ecosystem was catching its breath after last week’s TanStack Router compromise, the Mini Shai-Hulud supply chain worm has continued its relentless march. Developed by the thre

If you’ve ever built a web application that handles user uploads, you know the drill. You need to resize an avatar, generate a thumbnail, or convert a massive JPEG into a modern WebP format. For years, the undisputed king of this domain in the Node.js ecosystem has been sharp.
But sharp comes with a catch: heavy native module installs, platform-specific binaries, and occasional compilation headaches.
Bun is changing the game again. With its latest release, Bun now ships with Bun.Image—a built-in, chainable image processing API that handles JPEG, PNG, WebP, GIF, and BMP out of the box with zero native module installs.
Let’s dive into what makes Bun.Image a drop-in, ultra-fast alternative for server-side image operations.
Bun.Image provides a beautiful, fluent API for decoding, transforming, and encoding images. Because it’s built directly into the runtime, it requires no external dependencies.
Here is how simple it is to resize, rotate, and convert a photo to WebP:
await Bun.file("photo.jpg")
.image()
.resize(1024, 1024, { fit: "inside" })
.rotate(90)
.webp({ quality: 85 })
.write("thumb.webp");
One of Bun's coolest features is how deeply integrated Bun.Image is with the web platform. You can pass a Bun.Image instance directly into a standard web Response. Bun will handle the processing and automatically set the correct Content-Type header.
Here is a complete example of an HTTP server that generates a 200x200 JPEG thumbnail on the fly from an uploaded image:
Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
if (req.method === "POST" && url.pathname === "/thumbnail") {
const formData = await req.formData();
const upload = formData.get("image");
if (upload instanceof File) {
// Generate a thumbnail and stream it directly back to the client
return new Response(
new Bun.Image(upload).resize(200, 200, { fit: "cover" }).jpeg()
);
}
}
return new Response("Send a POST request with an 'image' file.", { status: 400 });
},
});
Bun.Image is incredibly flexible with what it accepts and how it outputs data.
You don’t have to worry about converting formats before feeding them to the pipeline. It natively accepts:
File path strings ("path/to/image.jpg")
ArrayBuffer / TypedArray (using zero-copy memory allocation)
Blob, BunFile, and S3File
data: URLs
The chainable pipeline gives you granular control over your assets:
Geometry: .resize(w, h?, {filter, fit, withoutEnlargement}), .rotate(90|180|270), .flip(), and .flop().
Color: .modulate({brightness, saturation}).
Advanced Filters: All standard sharp filters are supported, including nearest, bilinear, cubic, lanczos3, and the ultra-modern mks2021.
Except for .metadata(), all image processing runs entirely off the main thread, keeping your server responsive. You can output your final image using:
.bytes(), .buffer(), or .blob()
.toBase64() or .dataurl()
.write(dest) (saves directly to disk)
Modern UI patterns require displaying a tiny, blurred placeholder while a large image loads. Bun.Image makes this a one-liner using Thumbhash.
// 1. Grab image metadata
const meta = await new Bun.Image("hero.jpg").metadata();
console.log(`Dimensions: \({meta.width}x\){meta.height}, Format: ${meta.format}`);
// 2. Generate a blur-up thumbhash data URL
const placeholderUrl = await Bun.file("hero.jpg")
.image()
.placeholder(); // Returns a tiny thumbhash data URL
To keep binary sizes small, Bun handles core web formats identically across all platforms using statically linked codecs. For heavier, ecosystem-specific formats (like HEIC and AVIF), it lazily resolves native OS system backends (like Apple's ImageIO or Windows WIC) for zero startup cost.
With Bun.Image, the Bun team has eliminated one of the last major reasons developers had to rely on complex external C++ bindings for simple server side tasks. It’s fast, incredibly lightweight on developer workflows, and fits perfectly into standard Web APIs.
Give it a spin in your next Bun project! Turn on your servers, drop sharp, and start chaining.