wasm-image-optimization

April 20, 2026 · View on GitHub

High-performance image conversion and resizing tool leveraging WebAssembly (Emscripten). Built on the Skia rendering engine, it supports animations (GIF/WebP) and modern formats (AVIF/SVG/ThumbHash).

Tip

If you need to generate image files from HTML/CSS, please use the satoru-render library.

Playground

https://node-libraries.github.io/wasm-image-optimization/

Features

  • Multi-format Support: Supports major raster formats and SVG loading.
  • Animation Support: Supports loading GIF and WebP animations. Animated WebP is recommended for output.
  • Cropping: Supports cropping to a specified rectangular region before resizing.
  • High-Quality Resizing: Supports fit options (contain, cover, fill) with aspect ratio preservation.
  • Intelligent Animation Conversion: Automatically switches the output format to webp if animations are enabled and the source is animated.
  • Fast Execution: High-speed image processing using C++20 and SIMD (msimd128).
  • TypeScript Ready: Provides type-safe wrappers for easy integration.
  • Multi-threaded: Supports parallel processing using Web Workers / Worker Threads.
  • Multi-environment: Works seamlessly across Node.js, Cloudflare Workers, Deno, and Browsers.
  • Lightweight: Optimized binary size (approx. 7.4MB for the single-file bundle) by removing unnecessary dependencies like FreeType.

Supported Formats

FormatInput (Decoding)Output (Encoding)Notes
PNG
JPEG
WebPSupports animations
AVIFPowered by AOM encoder / dav1d decoder
ThumbHashReturns a compact image placeholder hash
RAWReturns uncompressed 32-bit RGBA pixel data
GIF-Input only (supports animations)
SVG-High-fidelity rendering via SkSVGDOM
BMP-
NoneReturns original data with metadata

Installation

pnpm add wasm-image-optimization

CLI Usage

After installation, the wasm-image-optimization command will be available.

# Basic conversion (default is WebP)
wasm-image-optimization input.png

# Specify format and quality
wasm-image-optimization input.jpg -f avif -q 80

# Convert maintaining animation
wasm-image-optimization input.gif -f webp -a

# Specify encoding speed (e.g., for AVIF)
wasm-image-optimization input.png -f avif -s 0

# Crop and resize
wasm-image-optimization input.png --crop 10,10,200,200 -w 100

# Resize and save with a different name
wasm-image-optimization input.png -w 800 -h 600 -o resized.webp

Library Usage (TypeScript)

Basic Usage

import { optimizeImage } from 'wasm-image-optimization';


const inputBuffer = ...; // Uint8Array or ArrayBuffer

const result = await optimizeImage({
  image: inputBuffer,
  crop: { x: 0, y: 0, width: 400, height: 400 }, // specify crop region
  width: 800,
  height: 600,
  fit: 'contain', // 'contain' | 'cover' | 'fill' (default: 'contain')
  format: 'webp',  // 'none' | 'png' | 'webp' | 'jpeg' | 'avif' | 'raw' | 'thumbhash'
  quality: 85,
  speed: 6,       // 0-10 (encoding speed for AVIF, etc.)
  animation: true // maintain animation if possible
});

// Result structure
// {
//   data: Uint8Array,           // processed image data
//   originalWidth: number,      // source width
//   originalHeight: number,     // source height
//   originalAnimation: boolean, // true if source was animated
//   originalFormat: string,     // source format (e.g., "jpeg")
//   width: number,              // output width
//   height: number,             // output height
//   animation: boolean,         // true if output is animated
//   format: string              // output format
// }

Multi-threading (Workers)

Use Workers for high-throughput processing without blocking the main thread.

import { optimizeImage } from "wasm-image-optimization/workers";

const result = await optimizeImage({
  image: inputBuffer,
  width: 800,
  format: "png",
});

Cloudflare Workers

Use the specialized workerd entry point for edge runtimes.

import { optimizeImage } from "wasm-image-optimization/workerd";

const result = await optimizeImage({
  image: inputBuffer,
  width: 800,
  format: "avif",
});

Build

Prerequisites

  • Emscripten (emsdk): Ensure the latest version is installed and environment variables are set.
  • vcpkg: Used for managing C++ dependencies.

Steps

# Install dependencies
pnpm install

# Configure CMake (using Ninja)
pnpm wasm:configure

# Build Wasm
pnpm wasm:build

Tech Stack

  • Core: Skia, libavif (AOM / dav1d), Wuffs, expat
  • Runtime: WebAssembly (Emscripten)
  • Language: C++20, TypeScript

License

MIT